如何在C预处理器中使用#if在#define中?

Wxy*_*Wxy 46 c c-preprocessor

我想编写一个宏,根据其参数的布尔值吐出代码.所以说DEF_CONST(true)应该扩展到const,并且DEF_CONST(false)应该扩展为无.

显然,以下方法不起作用,因为我们不能在#defines中使用另一个预处理器:

#define DEF_CONST(b_const) \
#if (b_const) \
  const \
#endif
Run Code Online (Sandbox Code Playgroud)

vla*_*adr 50

您可以使用宏标记连接来模拟条件,如下所示:

#define DEF_CONST(b_const) DEF_CONST_##b_const
#define DEF_CONST_true const
#define DEF_CONST_false
Run Code Online (Sandbox Code Playgroud)

然后,

/* 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 */
Run Code Online (Sandbox Code Playgroud)

另外,允许将宏参数传递给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 */
Run Code Online (Sandbox Code Playgroud)

您可能还会考虑更简单(尽管可能不太灵活):

#if b_const
# define DEF_CONST const
#else /*b_const*/
# define DEF_CONST
#endif /*b_const*/
Run Code Online (Sandbox Code Playgroud)

  • 是的 - 标记粘贴或字符串化('##`'或'`#`')预处理程序运算符几乎总是需要一个间接级别来按需运行:http://stackoverflow.com/questions/1767683/c-programming -preprocessor-宏-AS-令牌/ 1769037#1769037 (2认同)

Gra*_*amS 7

把它作为一个paramterised宏有点奇怪.

为什么不做这样的事情:

#ifdef USE_CONST
    #define MYCONST const
#else
    #define MYCONST
#endif
Run Code Online (Sandbox Code Playgroud)

然后你可以写这样的代码:

MYCONST int x = 1;
MYCONST char* foo = "bar";
Run Code Online (Sandbox Code Playgroud)

如果你用define USE_CONST定义(例如通常-DUSE_CONST在makefile或编译器选项中的某些东西),那么它将使用consts,否则它将不会.

编辑:其实我看到弗拉德在他的答案结束时覆盖了那个选项,所以给他+1 :)