2010-05-14 3 views
34

Voglio scrivere una macro che sputa fuori il codice in base al valore booleano del suo parametro. Così dicono DEF_CONST(true) deve essere esteso in const, e DEF_CONST(false) deve essere esteso nel nulla.preprocessore C: using #if all'interno di #define?

Chiaramente il seguente non funziona perché non possiamo usare un altro preprocessore all'interno #defines:

#define DEF_CONST(b_const) \ 
#if (b_const) \ 
    const \ 
#endif 

alcuna idea su come farlo?

+4

Qual è il punto di questo? Avete un esempio concreto, perché questo sembra un po 'strano ... –

+0

Vedere anche . – Rhubbarb

risposta

44

È possibile simulare condizionali utilizzando macro token concatenation come segue:

#define DEF_CONST(b_const) DEF_CONST_##b_const 
#define DEF_CONST_true const 
#define DEF_CONST_false 

Poi,

/* OK */ 
DEF_CONST(true) int x; /* expands to const int x */ 
DEF_CONST(false) int y; /* expands to int y */ 

/* NOT OK */ 
bool bSomeBool = true;  // technically not C :) 
DEF_CONST(bSomeBool) int z; /* error: preprocessor does not know the value 
           of bSomeBool */ 

Inoltre, consentendo il passaggio di parametri macro a DEF_CONST stesso (come giustamente sottolineato da Gman e altri):

#define DEF_CONST2(b_const) DEF_CONST_##b_const 
#define DEF_CONST(b_const) DEF_CONST2(b_const) 
#define DEF_CONST_true const 
#define DEF_CONST_false 

#define b true 
#define c false 

/* OK */ 
DEF_CONST(b) int x;  /* expands to const int x */ 
DEF_CONST(c) int y;  /* expands to int y */ 
DEF_CONST(true) int z; /* expands to const int z */ 

Si può anche considerare il molto semplice ler (anche se potenzialmente meno flessibile):

#if b_const 
# define DEF_CONST const 
#else /*b_const*/ 
# define DEF_CONST 
#endif /*b_const*/ 
+0

Errore di battitura in quanto sopra, ho appena perso il segno di modifica. Dovrebbe essere #define DEF_CONST (b_const) CONCATENATE (DEF_CONST_, b_const) '. – GManNickG

+2

Yup - incollare simbolico o stringizing (''##'' o ''' #') gli operatori del preprocessore quasi sempre davvero bisogno di un livello di indirezione di lavorare, se lo desideri: http://stackoverflow.com/questions/1767683/c- gettoni di programmazione-preprocessore-macro-as-/ 1769037 # 1769037 –

5

Facendolo come una macro parametrizzata è un po 'strano.

Perché non fare qualcosa di simile:

#ifdef USE_CONST 
    #define MYCONST const 
#else 
    #define MYCONST 
#endif 

Quindi è possibile scrivere codice come questo:

MYCONST int x = 1; 
MYCONST char* foo = "bar"; 

e se si compila con USE_CONST definita (ad esempio in genere qualcosa -DUSE_CONST nel makefile o opzioni del compilatore), quindi userà i conts, altrimenti non lo farà.

Edit: In realtà vedo Vlad coperto che l'opzione alla fine della sua risposta, in modo da +1 per lui :)