0

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)) ?

6
  • 3
    Identifiers that start with two underscores or with one underscore and a capital letter are reserved for use by the language implementation.
    – Carl Norum
    Commented Dec 21, 2012 at 22:31
  • Seems very similar to efesx.com/2010/08/31/overloading-macros and efesx.com/2010/07/17/… You are most welcome to have a look.
    – rmn
    Commented Dec 21, 2012 at 22:32
  • Normally, I'd say write a loop that goes through the arguments and checks each defined... however, if defined is used in the context of a preprocessor directive, that's a no-go. Commented Dec 21, 2012 at 22:34
  • The code you provided is an example of what you want in the general case or you need exactly that macro?
    – effeffe
    Commented Dec 21, 2012 at 23:13
  • @CarlNorum: I agree. I just provided it as an example and to distinguish between FOO and _FOO.
    – Arindam
    Commented Dec 21, 2012 at 23:34

2 Answers 2

3

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));
2

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.

1
  • 2
    Unfortunately this is forbidden by the standard. define is not allowed to appear in a macro expansion. Commented Dec 21, 2012 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.