How to test if a macro identifier is defined without using #ifdef?

154 Views Asked by At

Does anyone know how to, or if it's even possible to, create a variadic macro that expands to 0 if it's argument is not a defined macro, but expands to 1 if it's argument is a defined macro? (I'm using c99.)

#define BOB
#define SUE 45
#define IS_DEFINED(...) ???
IS_DEFINED(JOE)  <---- expands to 0
IS_DEFINED(BOB)  <---- expands to 1 (it's okay if this one doesn't work)
IS_DEFINED(SUE)  <---- expands to 1

EDIT: I specifically don't want any #if-related solutions... it needs to be a variadic macro (if that's possible) so I can do things like this:

#define CAT_(x, y) x ## y
#define CAT(x, y) CAT_(x, y)
#define CLEANUP0(...) ABC  <--- treats __VA_ARGS__ one way
#define CLEANUP1(...) XYZ  <--- treats __VA_ARGS__ a different way
#define CLEANUP(...) CAT(CLEANUP, IS_DEFINED(DEFAULT))(__VA_ARGS__)

Where ABC & XYZ are placeholders for other expansions that treat __VA_ARGS__ very differently.

1

There are 1 best solutions below

2
On

You can check whether a macro is defined with defined(), however this only works in the same circumstances where an #ifdef works (as far as I'm aware). I don't think this is possible but I might be mistaken.

Edit:

I don't know if this helps with what you want because the result will not be a constant expression. However if you want you could define the following macros:

#define _IS_DEFINED(...) (!!*#__VA_ARGS__)
#define IS_DEFINED(...) _IS_DEFINED(__VA_ARGS__)
#define BOB

if we now evaluate this we will get

int main() {
        printf("%d\n", IS_DEFINED(BOB));
}

which will give us

0

This is because IS_DEFINED(BOB) expands to (!!*""). In this case "" is just a pointer to some NUL byte in your .data section and dereferencing it will yield 0. But again, this is not a constant expression and as such the value is only avaliable to further usage in C and not the preprocessor. It also doesn't evaluate the second possibility as you wanted (like the example shows).