我想编写一个宏,根据其参数的布尔值输出代码。所以说,DEF_CONST(true)
应该扩展为 const
,而 DEF_CONST(false)
应该扩展为空。
显然下面的代码不起作用,因为我们不能在 #define 中再使用另一个预处理器:
#define DEF_CONST(b_const) \
#if (b_const) \
const \
#endif
我想编写一个宏,根据其参数的布尔值输出代码。所以说,DEF_CONST(true)
应该扩展为 const
,而 DEF_CONST(false)
应该扩展为空。
显然下面的代码不起作用,因为我们不能在 #define 中再使用另一个预处理器:
#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 */
此外,如GMan和其他人正确指出的那样,允许将宏参数传递给DEF_CONST本身:
#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*/
#define DEF_CONST(b_const) CONCATENATE(DEF_CONST_, b_const)
。 - GManNickG##
”或“#
”)预处理器运算符几乎总是需要一定程度的间接性才能按预期工作:http://stackoverflow.com/questions/1767683/c-programming-preprocessor-macros-as-tokens/1769037#1769037 - Michael Burr#ifdef USE_CONST
#define MYCONST const
#else
#define MYCONST
#endif
MYCONST int x = 1;
MYCONST char* foo = "bar";
USE_CONST
的编译选项(例如在makefile或编译器选项中通常会有-DUSE_CONST
),则它将使用常量,否则它不会使用。
编辑:实际上我看到Vlad在他的答案末尾涵盖了该选项,所以给他点赞 :)
_Generic
是一个例子。您可能需要检查uintmax_t
是否具有与unsigned long long
不同的基础类型。 - 12431234123412341234123