(C99)Expand a macro in a different macro

158 Views Asked by At

I have a function in my program that takes 3 arguments. Some times in the code there is a macro defining 2 of these parameters.

So this:

void func(int x, int y, int z){...}

Can be invoked like this:

#define PAR 10,20
int z = 3;
func(PAR, z);

Now, I need to change my code so that the function is called like a macro for another function.

#define func(X,Y,Z) func2(X,Y,Z,#Z)

This works fine if X and Y are really passed as variables. Is there any way to make it work also with the macro PAR?

I'm using GCC 4.6

2

There are 2 best solutions below

0
On BEST ANSWER

You can do this with an extra level of indirection, (ab)using variadic macros:

#include <stdio.h>
#define PAR 2,3
#define F(...) G(__VA_ARGS__)
#define G(a,b,c) H(a,b,c)
void H(int a, int b, int c) {
  printf("%d %d %d\n", a , b, c);
}
int main() {
  F(PAR, 42);
  return 0;
}

There is probably a better solution for the underlying problem.

1
On

No, I don't believe so. When you define

#define func(X,Y,Z) func2(X,Y,Z,#Z)

You're defining a function-like macro. func(X,Y,Z) actually takes three arguments - and it has to take three arguments. Remember, the preprocessor and not the compiler is interpreting func(PAR, Z).

I've struggled to find any documentation, but it makes sense that the first thing the preprocessor will do (considering that func() is the outer element) is to check to see if the arguments to func() are valid. Then it will place the arguments into func2() and will then expand any macros that were passed as arguments. The code I placed below seems to back up this claim.

Following this logic, the preprocessor will see that func(PAR, Z) isn't a valid call because an argument is missing, which will then throw the error

13:12: error: macro "func" requires 3 arguments, but only 2 given

func(X, Y, Z) will work so long as X and Y are valid macros or variables.

Code (this will give you warnings because there is no function declaration, but the output will be "3 14 3" as expected):

#include <stdio.h>
#include <stdlib.h>

#define PAR 10,20
#define MAR 3
#define WAR 14
#define func(X,Y,Z) print(X, Y, Z)

int Z = 3;

int main(void){

        func(MAR,WAR,Z);

        return 0;
}

void print(int x, int y, int c){

        printf("%d %d %d\n", x, y, c);

}

Out of curiosity, why are you doing this (I don't have enough reputation to comment yet FYI).