C虚拟操作

C虚拟操作,c,C,我无法想象编译器在没有左值的情况下会做什么,例如: 数量>>1; 我的直觉告诉我,由于优化,编译器将从编译中丢弃这一行,如果删除优化,会发生什么? 它是否使用寄存器进行操作?或者它的行为是否像是一个函数调用,因此参数被传递到堆栈,而使用的内存被标记为已释放?还是将其转换为NOP操作? 我可以使用VS++调试器查看正在发生的情况吗? 感谢您的帮助。在您给出的示例中,它将放弃该操作。它知道该操作没有副作用,因此不需要发出代码来执行语句以生成正确的程序。如果禁用优化,编译器仍可能发出代码。如果启用优化

我无法想象编译器在没有左值的情况下会做什么,例如: 数量>>1; 我的直觉告诉我,由于优化,编译器将从编译中丢弃这一行,如果删除优化,会发生什么? 它是否使用寄存器进行操作?或者它的行为是否像是一个函数调用,因此参数被传递到堆栈,而使用的内存被标记为已释放?还是将其转换为NOP操作? 我可以使用VS++调试器查看正在发生的情况吗?
感谢您的帮助。

在您给出的示例中,它将放弃该操作。它知道该操作没有副作用,因此不需要发出代码来执行语句以生成正确的程序。如果禁用优化,编译器仍可能发出代码。如果启用优化,编译器也可能发出代码——这不是完美的

您可以使用Microsoft编译器的
/FAsc
命令行选项查看编译器发出的代码。该选项将创建一个列表文件,其中包含编译器的目标代码输出以及相关的源代码

您还可以在调试器中使用“查看反汇编”来查看编译器生成的代码


在优化代码上使用“查看反汇编”或
/FAsc
,我希望不会看到编译器发出任何代码。

在您给出的示例中,它会放弃该操作。它知道该操作没有副作用,因此不需要发出代码来执行语句以生成正确的程序。如果禁用优化,编译器仍可能发出代码。如果启用优化,编译器也可能发出代码——这不是完美的

您可以使用Microsoft编译器的
/FAsc
命令行选项查看编译器发出的代码。该选项将创建一个列表文件,其中包含编译器的目标代码输出以及相关的源代码

您还可以在调试器中使用“查看反汇编”来查看编译器生成的代码


在优化代码上使用“查看反汇编”或
/FAsc
,我希望不会看到编译器发出任何代码。

假设
number
是整数类型的正则变量(而不是
volatile
),则任何有能力的优化编译器(Microsoft、Intel、GNU、IBM等)都不会生成任何内容。不是
nop
,没有使用寄存器等

如果禁用了优化(在“调试构建”中),那么编译器可能会“按您的要求执行”,因为它没有意识到它不会对代码产生副作用。在这种情况下,值将加载到寄存器中,右移一次。结果不会存储在任何地方。编译器将执行“无用代码消除”作为优化步骤之一——我不确定是哪一步,但对于这类相对简单的事情,我希望编译器能够用相当基本的优化设置来解决。在某些情况下,涉及循环等,编译器可能不会优化代码,直到启用一些更高级的优化设置

如注释中所述,如果变量是易失性的,则必须读取
number
表示的内存,因为编译器必须读取
volatile
内存

在VisualStudio中,如果您“查看反汇编”,它应该向您显示编译器生成的代码


最后,如果这是C++,也有可能变量不是正则整数类型,当编译器看到这个代码时,函数“代码>代码>操作符> <代码> -这个函数可能会有副作用,除了返回结果,所以可能必须执行。但在C语言中,情况并非如此,因为没有运算符重载。

假设
number
是整数类型的正则变量(而不是
volatile
),那么任何有能力的优化编译器(Microsoft、Intel、GNU、IBM等)都不会生成任何内容。不是
nop
,没有使用寄存器等

如果禁用了优化(在“调试构建”中),那么编译器可能会“按您的要求执行”,因为它没有意识到它不会对代码产生副作用。在这种情况下,值将加载到寄存器中,右移一次。结果不会存储在任何地方。编译器将执行“无用代码消除”作为优化步骤之一——我不确定是哪一步,但对于这类相对简单的事情,我希望编译器能够用相当基本的优化设置来解决。在某些情况下,涉及循环等,编译器可能不会优化代码,直到启用一些更高级的优化设置

如注释中所述,如果变量是易失性的,则必须读取
number
表示的内存,因为编译器必须读取
volatile
内存

在VisualStudio中,如果您“查看反汇编”,它应该向您显示编译器生成的代码


最后,如果这是C++,也有可能变量不是正则整数类型,当编译器看到这个代码时,函数“代码>代码>操作符> <代码> -这个函数可能会有副作用,除了返回结果,所以可能必须执行。但在C中不可能是这种情况,因为没有运算符重载。

为什么不查看生成的程序集?我确信编译器将简单地消除表达式。这里没有符合标准的答案,只要程序的语义保持不变,编译器就可以做任何它想做的事情。实际上,如果
number
volatile
的话,编译器必须小心处理,不能仅仅消除表达式-读取
volatile
var