I want to take this:
typedef int (*PTR_FUN)(int);
typedef int (*PTR_FUN_FUN)(PTR_FUN, PTR_FUN);
And define it like this:
MAKE_FUNCTION_TYPE(PTR_FUN, int, int);
MAKE_FUNCTION_TYPE(PTR_FUN_FUN, PTR_FUN, PTR_FUN, int);
...where the number of arguments is dynamic, and the last argument is the return type.
If not possible to put the last arg as return type, then as the second arg.
What you want is a variadic macro, which can take an arbitrary number of arguments. The syntax is #define MACRO(fixedarg1, fixedarg2, ...)
. In the body of the macro, you simply use __VA_ARGS__
to refer to all of the variable arguments.
Unfortunately, you can't make the last arg the return type, because you have to treat the entire block of variable arguments uniformly and they must come last. However, you can make the second arg the return type very easily:
#define MAKE_FUNCTION_TYPE(name, ret, ...) typedef ret (*name)(__VA_ARGS__)
MAKE_FUNCTION_TYPE(v_i, int);
MAKE_FUNCTION_TYPE(i_v, void, int);
MAKE_FUNCTION_TYPE(ii_cp, char *, int, int);
This is equivalent to
typedef int (*v_i)();
typedef void (*i_v)(int);
typedef char * (*ii_cp)(int, int);
which you can check using cc -E
.