考虑以下简单代码:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
您可以看到,也gcc
没有clang
优化对的潜在调用g
。在我的理解中,这是正确的:抽象机器假定volatile
变量随时可能更改(由于例如被硬件映射),因此将false
初始化不断折叠到if
检查中将是错误的。
但是MSVC g
完全消除了对的调用(保留对文件的读写volatile
!)。这是符合标准的行为吗?
背景:我有时会使用这种结构来即时打开/关闭调试输出:编译器必须始终从内存中读取值,因此在调试过程中更改变量/内存应相应地修改控制流。 。MSVC输出确实重新读取了该值,但忽略了该值(可能是由于不断折叠和/或消除了死代码),这当然违背了我的意图。
编辑:
volatile
此处讨论了对读写的消除:是否允许编译器优化局部volatile变量?(感谢内森!)。我认为该标准非常明确,即必须进行那些读写操作。但是,该讨论并未涵盖编译器将这些读取结果视为理所当然并基于此进行优化是否合法。我想这是标准中未指定的/未指定的,但是如果有人证明我做错了,我会很高兴。我当然可以制作
x
一个非局部变量来避免该问题。这个问题更多是出于好奇。