I'm aware of multiple Q&As [1, 2]that touch closely on this subject, and I've tried to implement their solutions but the fact that I need to use the . in my concatenation seems to be causing me trouble.
This is what I want:
#include <stdio.h>
#define PROPERTY .value1
#define MAKE_PROP(var) var##PROPERTY
typedef struct {
int value1;
int value2;
} Node;
int main(void) {
Node node;
node.value1 = 1;
node.value2 = 2;
// MAKE_PROP(node) should evaluate to "node.value1".
printf("%d", MAKE_PROP(node));
return 0;
}
However it's giving me all sorts of errors. If I try the PASTER-EVALUATE idea from [2] then it tells me "pasting "." and "PROPERTY" does not give a valid preprocessing token".
Anyone know how to accomplish what I need? It's essential that it stays general and that I can use the var
as this is something I'd like to call multiple times on different variable names.
It's not working for two reasons:
The token concatenation operator suppresses the expansion of macros that are used as its operands. So you get nodePROPERTY
. The solution to that is to add a level of indirection:
#define PROPERTY .value1
#define CONCAT(a, b) a##b
#define MAKE_PROP(var) CONCAT(var, PROPERTY)
Now PROPERTY
is expanded before being fed as an argument to CONCAT
.
The result of concatenating tokens must be a single valid token, but node.value1
is 3 tokens (node
, .
and value1
).
Now, it just so happens that you don't need concatenation at all, you just need to build the expression (node .value1)
which can be done with following simple macros1:
#define PROPERTY value1
#define MAKE_PROP(var) ( (var).PROPERTY )
1: simplified with the help of Lundin.