Я хочу записать макрос, который выкладывает код на основе булева значения его параметра. Поэтому скажите DEF_CONST(true)
должен быть расширен в const
, и DEF_CONST(false)
не должен быть расширен ни во что.
Очевидно следующее не работает, потому что мы не можем использовать другой препроцессор внутри #defines:
#define DEF_CONST(b_const) \
#if (b_const) \
const \
#endif
Вы можете моделировать условные выражения, используя конкатенацию маркеров макроса следующим образом:
#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*/
Делать это как макрос с параметрами немного странно.
Почему бы просто не сделать что-то вроде этого:
#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 ему :)