我无法想象编译器会做什么,例如没有像这样的左值: 数>大于1; 我的直觉告诉我,由于优化,编译器会从编译中丢弃这一行,如果优化被删除会发生什么? 它是否使用寄存器来进行操作?或者它是否像是一个函数调用,所以参数传递给堆栈,并且使用的内存被标记为已释放?或者是否将其转换为NOP操作? 我能看到使用VS ++调试器发生了什么吗? 感谢您的帮助。
答案 0 :(得分:1)
在您给出的示例中,它会丢弃该操作。它知道操作没有副作用,因此不需要发出代码来执行语句以产生正确的程序。如果禁用优化,编译器仍可能发出代码。如果启用优化,编译器可能仍会发出代码 - 它并不完美。
您可以使用Microsoft编译器的/FAsc
命令行选项查看编译器发出的代码。该选项创建一个列表文件,其中包含编译器的目标代码输出,其中散布着相关的源代码。
你也可以使用"查看反汇编"在调试器中查看编译器生成的代码。
使用"查看反汇编"或者/FAsc
关于优化代码,我希望看到编译器没有发出代码。
答案 1 :(得分:0)
假设number
是整数类型的常规变量(不是volatile
),那么任何有能力的优化编译器(Microsoft,Intel,GNU,IBM等)都将生成正好的NOTHING。不是nop
,没有使用寄存器等。
如果禁用了优化(在"调试版本中#34;),那么编译器可能会“按照你要求的那样做”,因为它没有意识到它没有" #39; t代码有副作用。在这种情况下,该值将被加载到寄存器中,右移一次。结果不会存储在任何地方。编译器将执行"无用的代码消除"作为优化步骤之一 - 我不确定哪一个,但对于这种相对简单的事情,我希望编译器能够找到相当基本的优化设置。在某些情况下,如果涉及循环等,编译器可能不会优化代码,直到启用某些更高级的优化设置。
正如评论中所提到的,如果变量是易失性的,则必须读取由number
重新编写的内存,因为编译器必须读取volatile
内存。
在Visual Studio中,如果你"查看反汇编",它应该显示编译器生成的代码。
最后,如果这是C ++,那么变量也可能不是常规整数类型,当编译器看到这个代码时,函数operator>>
被调用 - 这个函数可能有 - 除了返回结果之外,还可能必须执行。但是在C中情况并非如此,因为没有运算符重载。