Reputation: 943
Is is possible to define a macro BREF(...):
struct bits
{
int b0:1;
int b1:1;
int b2:1;
int b3:1;
int b4:1;
int b5:1;
int b6:1;
int b7:1;
}
#define BREF(var,bit) ????
#define BAR 4
#define ALIAS BREF(foo,BAR)
unsigned char foo;
such that this statement:
ALIAS = 1;
expands to this:
((struct bits *)&foo)->b4 = 1;
and this:
int k = ALIAS;
to this:
int k = ((struct bits *)&foo)->b4;
So far, this is my implementation of BREF(...):
#define BREF(var,bit) (((struct bits *) &(var))->b##bit)
However, this only works if bit
is a literal numeral. I want to be able to pass in a macro variable that expands into a number. How can I make the C preprocessor expand bit
before concatenating it to b
?
Upvotes: 1
Views: 2124
Reputation: 400174
The trick is that the C preprocessor will expand macro arguments only if they are not being used with the stringizing (#
) or token-pasting (##
) operators. So, to make it work with a macro that expands to a numeric literal, add an extra layer of macros like so:
#define CONCAT(x, y) x ## y
#define BREF(var,bit) (((struct bits *) &(var))-> CONCAT(b, bit))
With this definition, bit
is no longer a direct argument of the token-pasting operator, so if it's a macro, it gets expanded before the token-pasting.
Upvotes: 3
Reputation: 17373
You can use an extra step of expansion, like this:
#define BITATTR(num) b##num
#define BREF(var,bit) (((struct bits *) &(var))->BITATTR(bit))
Upvotes: 2