考虑这个简单的代码:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
您可以看到gcc
和clang
都没有优化对g
的潜在调用。在我的理解中,这是正确的:抽象机器假设volatile
变量随时可能发生变化(由于例如被硬件映射),因此将false
初始化不断折叠到if
检查中错误。
但是MSVC完全消除了对g
的调用(尽管保持对volatile
的读写!)。这是符合标准的行为吗?
背景:我有时会使用这种结构来即时打开/关闭调试输出:编译器必须始终从内存中读取值,因此在调试期间更改该变量/内存应修改相应地控制流程。 MSVC输出确实重新读取了该值,但忽略了该值(可能是由于不断折叠和/或消除了死代码),这当然违背了我的意图。
编辑:
在此处讨论了对volatile
的读取和写入的消除:Is it allowed for a compiler to optimize away a local volatile variable?(感谢内森!)。我认为该标准非常明确,即发生了[
x
设置为非局部变量以避开该问题。这个问题更多是出于好奇。考虑以下简单代码:void g(); void foo(){volatile bool x = false;如果(x)g(); } https://godbolt.org/z/I2kBY7您可以看到gcc和clang都无法优化...