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

对于__noop,MSDN说它是编译器提供的内部函数.到(void) 0~为什么编译器会把它解释为无操作?这是C语言的一种棘手用法,还是该标准明确说明了这一点?或者甚至这与编译器实现有关?

推荐答案

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

EDIT:(根据Chris Lutz的 comments 更新)

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

#define noop ((void)0)

(void)可防止将其意外用作如下值

int x = noop;

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

C++相关问答推荐

C sscanf没有捕获第二个参数

C:gcc返回多个错误定义,但msvc—不""'

如何使用Python C API实现多线程程序?

为什么在此程序中必须使用Volatile关键字?

如何在IF语句中正确使用0.0

向上强制转换C中的数值类型总是可逆的吗?

VS代码';S C/C++扩展称C23真关键字和假关键字未定义

1处的解析器错误:yacc语法的语法错误

函数的限制限定指针参数允许优化调用方函数吗?

将返回的char*设置为S在函数中定义的字符串文字可能会产生什么问题?

Boyer Moore算法的简单版本中的未定义行为

处理EPOLL_WAIT中的接收数据和连接关闭信号

致命错误:ASM/rwan ce.h:没有这样的文件或目录.符号链接还不够

将字符串数组传递给C中的函数:`str[dim1][str_size]`vs`*str[dim1]`

链接到底是如何工作的,我在这里到底做错了什么

我在C程序的Flex/Bison中遇到语法错误

int * 指向int的哪个字节?

生成的头文件不包括用户定义的文件

RISC-V GCC编译器错误编译ASM代码

为什么孤儿进程在 Linux 中没有被 PID 1 采用,就像我读过的一本书中声称的那样?