int* foo()
{
volatile auto a = nullptr;
int* b = a;
return b;
}
int main()
{}
当使用 -Ofast 编译选项时,Clang 会为 foo
生成 以下 汇编代码。
mov qword ptr [rsp - 8], 0 # volatile auto a = nullptr;
xor eax, eax
ret
这意味着编译器假定从a
读取时没有副作用,基本上删除了代码中的int * b = a;
部分。
另一方面,GCC生成了略微不同的代码(链接)。
mov QWORD PTR [rsp-8], 0 # volatile auto a = nullptr;
mov rax, QWORD PTR [rsp-8] # int* b = a;
xor eax, eax
ret
在这里,编译器认为从a
读取确实产生了副作用,并保持一切不变。
问题是根据C++20标准,正确的行为是什么?
volatile
被认为是可观察的,尽管其详细含义是由实现定义的。(当然,标准并未说明应发出哪些特定指令。) - user17732522