为啥编译器抱怨这个宏声明
Posted
技术标签:
【中文标题】为啥编译器抱怨这个宏声明【英文标题】:Why compiler complain about this macro declaration为什么编译器抱怨这个宏声明 【发布时间】:2012-04-09 14:14:31 【问题描述】:为了调试方便,我写了以下宏,
1 #ifndef DEF_H
2 #define DEF_H
3 #define DEBUG_MODE
4 #define DEBUG_INFO(message) \
5 #ifdef DEBUG_MODE \
6 cout << message << endl; \
7 #endif \
8 #endif
但 gcc 抱怨如下
def.h:4: error: '#' is not followed by a macro parameter
def.h:1: error: unterminated #ifndef
这段代码有什么问题?我是否遗漏了一些重要的点?
【问题讨论】:
【参考方案1】:您不能在宏定义中包含#ifdef
s。你需要把它翻过来:
#ifdef DEBUG_MODE
#define DEBUG_INFO(message) cout << (message) << endl
#else
#define DEBUG_INFO(message)
#endif
【讨论】:
谢谢。那么如何使用宏来控制调试开关来实现目标。在客户端,我更喜欢只调用一行,例如 DEBUG_INFO("debug info") +1。另外,第 7 行后面有一个反斜杠,导致最后一行的 #endif 成为第 4 行的一部分,与第一行的 #ifndef 不匹配【参考方案2】:您不能将预处理器指令嵌入另一个预处理器指令(DEBUG_INFO
定义中的#ifdef DEBUG_MODE
)。相反,做类似的事情
#ifdef DEBUG_MODE
# define DEBUG_INFO(message) cout << message << endl
#else
# define DEBUG_INFO(message) 0
#endif
(这仍然不理想;防御性宏编码建议类似于
#ifdef DEBUG_MODE
# define DEBUG_INFO(message) do cout << message << endl; while (0)
#else
# define DEBUG_INFO(message) 0
#endif
也许inline
函数会更好。)
【讨论】:
“你不能在另一个预处理器指令中嵌入一个预处理器指令”,这并非适用于所有情况,是吗?例如#if、#ifdef 和 #ifndef【参考方案3】:我猜如果你在第 7 行吃“\”,那段代码就可以工作了。
【讨论】:
以上是关于为啥编译器抱怨这个宏声明的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 编译器抱怨在属性定义中使用 SPeL 表达式。为啥?
编写 if-else 编译器时会抱怨,但简而言之却没有,为啥? [复制]
Linux 上 Poco::Logger 的编译器错误 - 函数声明被视为宏