Assuming some_code()
is actually code
This can be tricky: if id
is expanded from another token, it could be something like (0)
instead of 0
, or 0x10
instead of 16
. Also, run-time values.
If you have a modern enough compiler, however, you can make use of dead code elimination:
#define M(id, ...) do { \
if (id) { \
some_code(__VA_ARGS__); \
} \
} while (/* CONSTCOND */ 0)
This will do the trick, even in a setting such as…
void
foo(int bar, int baz) {
M(bar, baz);
}
… and, since id
is supposed to be a constant in all other cases, the if
will be optimised away (even GCC 3.4.6 without any optimisation flags does that, for both zero and nōn-zero values, I just checked; LLVM will also do that, and many commercial Unix vendor compilers are likely to do so; PCC probably won’t, but is unlikely to be encountered by you).
So, this is not a pure-cpp solution, but one that’s likely to work in the wild, and it doesn’t invoke Undefined Behaviour or similar… fun… either.
The /* CONSTCOND */
is for lint, and the whole do { … } while (0)
block is commonly used around macros that contain control constructs, so they can be used universally.
If some_code
is not code but an arithmetic expression
In this case, the same solution becomes even shorter:
#define M(id, ...) ((id) ? some_code(__VA_ARGS__) : void)
Instead of void
at the end, substitute anything you wish to return if id
was zero. (I don’t believe the question warrants this, as writing some_code(__VA_ARGS__)
pretty much looks like a function taking arguments, but some commenting person insists on this.)