Question

I want to essentially have a macro shortener.

The macro, FOO(A,B,C) should expand to defined(_FOO_A) || defined(_FOO_B) || defined(_FOO_C).

Is that possible in GCC using variadic macro arguments and not actually writing 3 functions (FOO(A), FOO(A,B), FOO(A,B,C)) ?

Was it helpful?

Solution

It is not possible to have a macro to expand to something that contains the defined keyword:

If the token defined is generated as a result of this replacement process or use of the defined unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined.

So you can't do it with defined. If you are willing to relax that constraint by just testing the value of FOO_A_, FOO_B_, ... there are ways to do this by using P99. E.g just doing a logical or of a list of variables would be

#if P99_ORS(A, B, C)
...
#endif

where the P99_ORS expression expands to

((((A) || (B))) || (C))

and is then evaluated for #if the expression.

There would also be ways to expand that first into a token list of your liking, if you want to do some macro programming

#define P00_NAME_X(NAME, X, I) P99_PASTE2(NAME, X)
#define CONDITION(NAME, ...) P99_ORS(P99_FOR(FOO_, P99_NARG(__VA_ARGS__), P00_SEQ, P00_NAME_X, __VA_ARGS__))

such that

CONDITION(A, B, C, toto);

would expand to

((((((FOO_A) || (FOO_B))) || (FOO_C))) || (FOO_toto));

OTHER TIPS

Something like this?

#include <stdio.h>

#define FOO(A, B, C) (FOO_X(A) || FOO_X(B) || FOO_X(C))
#define FOO_X(x) defined(_FOO_##x)

// just to print it
#define QUOTE(...) QUOTE_AUX(__VA_ARGS__)
#define QUOTE_AUX(...) #__VA_ARGS__

int main(void)
{
    puts(QUOTE(FOO(a, b, c)));
}

EDIT: actually this results undefined behavior, in all C standards.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top