为什么(void)0在C和C++中没有操作?

leg*_*s2k 48 c c++ compiler-construction language-details

我在glibc中看到了debug printfs (void) 0,如果定义了NDEBUG,则内部定义为.同样__noop,Visual C++编译器也是如此.前者适用于GCC和VC++编译器,而后者仅适用于VC++.现在我们都知道上述两个语句都将被视为无操作,并且不会生成相应的代码; 但这是我怀疑的地方.

在这种情况下__noop,MSDN说它是编译器提供的内部函数.来(void) 0〜为什么编译器将其解释为没有操作?这是C语言的一个棘手的用法还是标准说明了它的明确性?或者甚至那与编译器实现有关?

Ale*_*ler 66

(void)0(+ ;)是一个有效的,但"无所事事"的C++表达式,就是一切.它不会转换为no-op目标体系结构的指令,只要语言需要完整语句(例如作为跳转标签的目标,或者在if子句的主体中),它就只是一个空语句作为占位符.

编辑:(根据Chris Lutz的评论更新)

应该注意的是,当用作宏时,比方说

#define noop ((void)0)
Run Code Online (Sandbox Code Playgroud)

所述(void)防止它被意外地用作值等

int x = noop;
Run Code Online (Sandbox Code Playgroud)

对于上面的表达式,编译器将正确地将其标记为无效操作.GCC吐痰error: void value not ignored as it ought to be和VC++咆哮'void' illegal with all types.

  • 你应该注意到,用作宏(比如`#define noop(void)0`),`(void)`防止它被意外地用作一个值(如`int x = noop;`. (47认同)
  • 感谢 Chris,澄清了为什么将类型强制转换为 void;它可以防止意外使用上述 noop exp。在类似赋值的表达中,现在我明白了。 (2认同)

小智 9

任何没有任何副作用的表达式都可以被编译器视为无操作,它不必为它生成任何代码(尽管可能).事实上,编译器(和人类)很容易看到没有副作用,然后不使用强制转换结果.