Visual Studio临时对象销毁时机是否符合C++标准?该行为是否合规?
MSVC临时对象销毁顺序是否符合C++标准?
根据C++标准,临时对象应在完整表达式末尾被销毁。但如下代码在Visual Studio中的表现与此不符:
#include <cstdio> struct Foo { Foo() = default; Foo(const Foo &) {} ~Foo() { std::printf("~Foo()\n"); } }; int foo(Foo f) { return 0; } void bar(int) { std::printf("bar\n"); } int main() { bar(foo(Foo())); }
按照标准预期,这段代码的输出应为:
bar ~Foo()
但使用MSVC编译运行时,实际输出为:
~Foo() bar
请问该行为是否被C++标准允许?
这个行为是符合C++标准的。
C++标准对于临时对象的销毁时机存在例外规则:当临时对象被用来初始化函数的非引用形参时,编译器可以选择在函数调用完成后立即销毁该临时对象,也可以延后到包含该函数调用的完整表达式末尾再销毁——只要保证该临时对象的所有使用都已完成即可。
回到这段代码:foo(Foo())中的临时Foo对象被传递给foo的按值形参f,此时编译器完全有权选择在foo返回后就销毁这个临时对象(也就是调用bar之前),这完全符合标准的规则。因此MSVC的输出是合法的,属于标准允许的实现选择,并非违反C++标准。
内容的提问来源于stack exchange,提问作者geza
相关产品推荐
相关产品推荐

