我在阅读一些源代码时发现了这一点。
#define MACRO(x) if((void) 0, (x)); else some_func();
我不完全理解操作符逗号和void转换背后的原因。这可能与宏保护有关,我知道(void)0
有时用于保护宏中的级联else
,例如if(...) then foo(); else (void)0
。
有关运算符逗号为什么的任何想法?
编辑:我开始认为这与owl (0,0)
有关。
答案 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)
确实意味着/完成了某些事情。