Voglio scrivere una macro che sputa il codice in base al valore booleano del suo parametro. Pertanto, DEF_CONST(true)
deve essere espanso in const
e DEF_CONST(false)
deve essere espanso in nulla.
Chiaramente quanto segue non funziona perché non possiamo usare un altro preprocessore all’interno di #defines:
#define DEF_CONST(b_const) \ #if (b_const) \ const \ #endif
È ansible simulare condizionali utilizzando la concatenazione di token macro 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 dei parametri macro a DEF_CONST stesso (come correttamente 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 più semplice (anche se potenzialmente meno flessibile):
#if b_const # define DEF_CONST const #else /*b_const*/ # define DEF_CONST #endif /*b_const*/
Farlo come una macro parametrizzata è un po ‘strano.
Perché non fare solo qualcosa del genere:
#ifdef USE_CONST #define MYCONST const #else #define MYCONST #endif
Quindi puoi scrivere un codice come questo:
MYCONST int x = 1; MYCONST char* foo = "bar";
e se si compila con USE_CONST
definito (ad es. tipicamente qualcosa -DUSE_CONST
nelle opzioni makefile o del compilatore) allora userà i consts, altrimenti non lo farà.
Edit: In realtà vedo che Vlad ha coperto quell’opzione alla fine della sua risposta, quindi +1 per lui 🙂