#define中的C ++ void cast和operator逗号

时间:2010-10-12 14:55:00

标签: c++ macros

我在阅读一些源代码时发现了这一点。

 #define MACRO(x)  if((void) 0, (x)); else some_func();

我不完全理解操作符逗号和void转换背后的原因。这可能与宏保护有关,我知道(void)0有时用于保护宏中的级联else,例如if(...) then foo(); else (void)0

有关运算符逗号为什么的任何想法?

编辑:我开始认为这与owl (0,0)有关。

3 个答案:

答案 0 :(得分:8)

我猜这个技巧用于防止用户在if条件下声明变量。您可能知道,在C ++中,这样做是合法的

if (int i = some_func()) {
   // you can use `i` here
}
else  {
   // and you can use `i` here
}

在该定义中使用逗号运算符将阻止像

这样的宏使用
MACRO(int i = some_func());

并强制用户仅使用表达式作为参数。

答案 1 :(得分:4)

虚空转换肯定会阻止调用重载的operator ,,因为你不能用void参数重载。这可以保证(void)0,无效。

为什么逗号运算符在那里?一个好问题。我真的不知道。

答案 2 :(得分:2)

这个看起来像,好像有人可能已经开始使用包含assert的某些代码,对其进行预处理,并将结果转换为宏。定义NDEBUG后,assert必须变得几乎没有 - 但从语法上讲,仍然需要生成一些占位符代码。例如,您可以在以下情况下使用它:

assert(x), *x = 1;

当您使用NDEBUG定义编译它时,它仍然需要编译,但assert不应该做任何事情。为了支持这一点,assert通常定义如下:

#undef assert
#ifdef NDEBUG
#define assert(x) ((void)0)
#else
#define assert(x) ((!!x) || __failassert(x, __FILE__, __LINE__))
#endif 

所以,如果有人开始使用上面的代码,然后查看预处理版本(定义了NDEBUG),他们会看到类似的内容:

((void *)0), *x = 1;

......如果他们不能很好地理解代码,他们可能会认为((void)0)确实意味着/完成了某些事情。