direttive - Come usare#if all'interno di#define nel preprocessore C?




direttive preprocessore c (2)

È possibile 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*/

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

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





c-preprocessor