gpt4 book ai didi

c++ - 当析构函数调用自动变量修改函数返回值时,MSVC14.1和gcc8.3之间观察到差异

转载 作者:行者123 更新时间:2023-12-03 07:27:37 25 4
gpt4 key购买 nike

考虑以下内容(使用C++ 14编译)

#include <iostream>
#include <vector>

// Foo adds an element to a std::vector passed by reference
// on construction in the destructor
struct Foo {
Foo(std::vector<double>& v) : m_v(v){
}
~Foo(){
m_v.push_back(1.0);
}
std::vector<double>& m_v;
};

std::vector<double> bar(){
std::vector<double> ret;
Foo foo(ret);
return ret;
}

int main(){
std::cout << bar().size() << "\n";
}
在gcc8.3中,输出为 1,这意味着 foo的析构函数会对返回的 vector 产生影响。
在MSVC14.1中,输出为 0。您可以通过将 Foo foo(ret);行替换为 {Foo foo(ret);}(即通过强制作用域)来强制输出与gcc8.3相同。
我不认为这是悬而未决的引用未定义行为(因为 retfoo之前声明),但是这可能是MSVC14.1中的错误(如果这样,我将创建一个错误报告)。有人有确切消息么?
参见 https://ideone.com/pnxWuJ

最佳答案

我认为C++ 20标准的相关部分是[stmt.return],它表示

The copy-initialization of the result of the call is sequenced before the destruction of temporaries at the end of the full-expression established by the operand of the return statement, which, in turn, is sequenced before the destruction of local variables (8.7) of the block enclosing the return statement


因此,应首先构造函数调用的结果(返回值),然后销毁 foo。由于返回值是在 foo的析构函数运行之前构造的,因此结果应为0。
[class.copy.elision]部分说

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects.


因此,两个编译器都可以认为是正确的。

关于c++ - 当析构函数调用自动变量修改函数返回值时,MSVC14.1和gcc8.3之间观察到差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64977541/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com