Как использовать #if внутри #define в препроцессоре C?

Я хочу записать макрос, который выкладывает код на основе булева значения его параметра. Поэтому скажите DEF_CONST(true) должен быть расширен в const, и DEF_CONST(false) не должен быть расширен ни во что.

Очевидно следующее не работает, потому что мы не можем использовать другой препроцессор внутри #defines:

#define DEF_CONST(b_const) \
#if (b_const) \
  const \
#endif
46
задан Ciro Santilli 新疆改造中心法轮功六四事件 9 May 2018 в 06:59
поделиться

2 ответа

Вы можете моделировать условные выражения, используя конкатенацию маркеров макроса следующим образом:

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

Затем

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

Также, позволяя передавать параметры макроса в сам DEF_CONST (как правильно указал GMan и другие):

#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 */

Вы также можете рассмотреть гораздо более простой (хотя потенциально менее гибкий):

#if b_const
# define DEF_CONST const
#else /*b_const*/
# define DEF_CONST
#endif /*b_const*/
50
ответ дан 26 November 2019 в 20:38
поделиться

Делать это как макрос с параметрами немного странно.

Почему бы просто не сделать что-то вроде этого:

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

Тогда вы можете написать код вроде этого:

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

и если вы компилируете с определенным USE_CONST (например, обычно что-то -DUSE_CONST в makefile или опциях компилятора), то он будет использовать константы, иначе - нет.

Edit: Вообще-то я вижу, что Влад рассмотрел этот вариант в конце своего ответа, так что +1 ему :)

7
ответ дан 26 November 2019 в 20:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: