宏定义中的#ifdef

57

可能是重复问题:
#define内使用#ifdef

当我尝试在宏中使用"#"字符时,该如何成功地使用呢? 当我做类似以下的事情时,它会报错:

#define DO(WHAT)        \
#ifdef DEBUG        \                           
  MyObj->WHAT()         \       
#endif              \
5个回答

72

你不能这样做。你必须这样做:

#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT) do { } while(0)
#endif

do { } while(0) 避免了空语句。例如,可以参考这个问题


那么,使用空语句可能会在某些C++编译器上出现问题?我的应用程序是跨平台的,包括OSX、Windows和Ubuntu。这样做安全吗? - JasonGenX
2
+1:do {} while(0) 结构是我在答案中忘记提到的。 - Oliver Charlesworth
3
使用内联函数而非宏定义的原因之一就是这个! - Bo Persson
1
@Bo Persson:您建议使用内联函数的解决方案是什么?请发帖。 - Nawaz
1
在这种情况下,MyObj必须作为参数传递给这些函数,因此它不是一个易于替换的功能。此外,您还必须处理指向成员的指针参数,这可能很快变得丑陋。话虽如此,我实际上并不喜欢使用宏来隐藏正在发生的事情,但问题已经提出了…… - Roger Lipscombe
显示剩余3条评论

13

它之所以尖叫,是因为你无法这样做。

我建议以下替代方案:

#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif

5
似乎您想要做的事情可以这样实现,而且不会遇到任何问题:
#ifdef DEBUG
#    define DO(WHAT) MyObj->WHAT()
#else
#    define DO(WHAT) while(false)
#endif

顺便提一下,最好使用NDEBUG宏,除非你有更具体的原因不使用它。 NDEBUG更广泛地用作表示无调试的宏。例如,标准的assert宏可以通过定义NDEBUG来禁用。你的代码将变成:

#ifndef NDEBUG
#    define DO(WHAT) MyObj->WHAT()
#else
#    define DO(WHAT) while(false)
#endif

1
你应该强调,因为 NDEBUG 表示无调试,所以 #ifdef 变成了 #ifndef - ilpelle

2
您可以像这样做相同的事情:
#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif

请参见其他正确的方法以避免空语句... - antlersoft

2
怎么样:
#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接