I have the following lines of code, created by a database export program:
typedef struct _s8_VARB
{
unsigned char _byte[8];
} s8_VARB;
const s8_VARB varb00[] = {
mMM(1,25,22,12,0,0,0,0,27)
mMM(0,1,29,12,0,0,0,0,21)
mMM(1,1,36,12,0,0,0,0,22)
}
The mMM
is a macro that I want to define with a functionality that will produce the following data during compilation:
const s8_VARB varb00[] = {
1,25,22,12,0,0,0,0,27,
1,1,36,12,0,0,0,0,22,
}
So it basically should check the 1st parameter. If it is 0, that complete line should omitted. If it is 1, all the parameters (except the 1st) should be 'put on the line', ending with a comma.
What I have tried is this:
#define COMMA ,
#define mMM(cond, a,b,c,d,e,f,g,h) (cond) ? (a),(b),(c),(d),(e),(f),(g),(h) COMMA :
But this is not working. Not even compiling, as gcc complains:
error: expected expression before ':' token
How should this macro definition should look like? Is this possible at all in C?
You can initialize an array with constant data only. A conditional statement is by definition not constant (even if it's known to the compiler at compile time).
Instead you could do it like this:
#define _mMM0(...)
#define _mMM1(...) {__VA_ARGS__},
#define mMM(cond, ...) _mMM##cond(__VA_ARGS__)
const unsigned char varb00[][8] = {
mMM(1,25,22,12,0,0,0,0,27)
mMM(0,1,29,12,0,0,0,0,21)
mMM(1,1,36,12,0,0,0,0,22)
};
I removed the struct and replaced it with its only member directly. In case C99 is not available, you can name every parameter as you used to do.
Here's a hackish solution. If the number of arguments is fixed and you can't use C99+, then you could list them explicitly instead of using ...
and __VA_ARGS__
.
#define mMM(x, ...) mMM##x(__VA_ARGS__)
#define mMM0(...)
#define mMM1(...) __VA_ARGS__,
The ##
operator pastes the token mMM
and the x
argument together to form a new macro name -- either mMM0
or mMM1
-- which is then called with the remaining arguments. mMM0()
in turn expands to nothing, and mMM1()
expands to its arguments.
(The extra trailing comma after the last element won't be a problem by the way. int a[] = { 1, 2, 3, }
is explicitly allowed syntax in C.)
As a side note, invoking a macro like
#define m(x) (x) ? 1 : 2
using e.g. m(0)
will simply expand it to (0) ? 1 : 2
. The ternary operator will not be handled in the preprocessor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With