Pregunta

Is there a way in this code

#include <stdio.h>

// #define t1

#define msg_a 1
#define msg_b 2
#define msg_c 3
#ifdef t1
    #define msg_d 4
    #define msg_e 5
#endif

#define call(msg) case msg_ ## msg: printf("msg_" #msg); break;

#define avail \
    call(a) \
    call(b) \
    call(c) \
    call(d) \
    call(e) \


int main(void)
{
    int test;

    test = 2;

    printf("test = %d\n", test);

    switch (test)
    {
        avail
    }

    printf("\nend\n");

    return 0;
}

to get (logically) the same result as if the bellow code works?

#define avail \
    call(a) \
    call(b) \
    call(c)
#ifdef t1
    call(d) \
    call(e) \
#endif

So, I don't want to generate code like case msg_b: printf("msg_" "b"); break; inside my switch if t1 is not defined.

Also, more defines like this maybe included, and then there will be

...
#ifdef t2
    #define msg_f 6
    #define msg_g 7
#endif
...

and again, this should works like this

#define avail \
    call(a) \
    call(b) \
    call(c)
#ifdef t1
    call(d) \
    call(e) \
#endif
#ifdef t2
    call(f) \
    call(g) \
#endif

Is there a way to get something similar to this?

¿Fue útil?

Solución

I'm not sure what you're trying to accomplish with this, so I can't really know that this is a good idea, but...

#ifdef t1
#define t1_calls call(d) \
                 call(e)
#else
#define t1_calls
#endif

#ifdef t2
#define t2_calls call(f) \
                 call(g)
#else
#define t2_calls
#endif

#define avail t1_calls t2_calls

Incidentally, I assume that this is just to show what you mean and you know about normal C conventions regarding macros (functions, capitalization, scoping, etc.)

Otros consejos

One straightforward way:

#ifdef t1
#define avail call(a); call(b); call(c); call(d); call(e);
#else
#define avail call(a); call(b); call(c); 
#endif

So you can extend this to get:

#ifdef t1
#define T1 call(d); call(e);
#else
#define T1 
#endif

#ifdef t2
#define T2 call(f); call(g);
#else
#define T2
#endif

#define avail call(a); call(b); call(c); T1 T2

Not elegantly.

Firstly, a macro cannot expand to preprocessor directives. Every directive must be visible at the toplevel without any expansion (among other things, it's syntactically impossible since there's no such thing as a multi-line macro - the \ escapes the newline, rather than including it - and directives rely on newlines as part of the syntax).

You can have conditional expansion within a macro (see here, here, etc.). But those are based on macros that expand to boolean values (or at least to some substitute for booleans). Unfortunately defined is an operator rather than a macro, which means it can only appear in preprocessor expressions, i.e. the argument to an #if directive. It cannot expand into anything that would be inserted into the program body, and thus cannot form part of a macro definition that relies on expansion to choose an action.

If you really want a static if macro, make t1, t2 etc. defined at all times (the choice being between two possible values rather than between defined and undefined), and use one of the other static-if techniques in the linked questions. Or better, reconsider your need for a static if at all: in most cases, it's better to use a C-level if statement and let the compiler optimise out the dead branch.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top