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

时间:2010-05-14 05:03:31

标签: c c-preprocessor

我想编写一个宏,根据其参数的布尔值吐出代码。因此,DEF_CONST(true)应该扩展为const,而DEF_CONST(false)应该扩展为无。

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

#define DEF_CONST(b_const) \
#if (b_const) \
  const \
#endif

2 个答案:

答案 0 :(得分:48)

您可以使用macro token concatenation模拟条件,如下所示:

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

答案 1 :(得分:7)

将它作为paramterised宏来做有点奇怪。

为什么不做这样的事情:

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

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

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

如果您使用USE_CONST进行编译(例如,在makefile或编译器选项中通常为-DUSE_CONST),那么它将使用consts,否则不会。

编辑:实际上我看到弗拉德在答案结尾处覆盖了这个选项,所以+1代表他:)