gpt4 book ai didi

c++ - RVO 在返回前覆盖参数中的值

转载 作者:可可西里 更新时间:2023-11-01 16:18:41 26 4
gpt4 key购买 nike

在 AIX 上使用 xlC 编译以下代码会生成打印“2 2”的代码。在带有 gcc 和 clang 的 Linux 上,它可靠地生成“3 3”。

#include <iostream>

struct Numbers
{
Numbers() : a(0) , b(0) { }
Numbers(int a, int b) : a(a), b(b) { }

int a;
int b;
};

Numbers combine(const Numbers& a, const Numbers& b)
{
Numbers x;
x.a = a.a + b.a;
x.b = a.b + b.b;
return x;
}

Numbers make()
{
Numbers a(1, 1);
Numbers b(2, 2);

a = combine(a, b);
return a;
}

int main()
{
Numbers a = make();
std::cerr << a.a << " " << a.b << "\n";
}

在我看来,AIX 正在将 RVO 应用于 combine 的返回值,因此当我创建 Numbers x 时,它最终会覆盖我的参数 a 使用默认初始化的 x

我在这里调用了一些未定义的行为吗?我希望在 combine(a, b) 被评估并分配给 a 之前,不会对 a 进行任何修改。

这与:用于 AIX 的 IBM XL C/C++,V12.1(5765-J02、5725-C72)版本:12.01.0000.0012

最佳答案

看起来编译器正在对复制赋值 (!) 执行复制省略,而实际上它只能在初始化时这样做。也就是说,编译器在初始化 x 时确实覆盖了与您的参数 a 关联的对象。将 RVO(对于 RVO 的某些定义)应用到 combine 的返回值本身并没有错。错误的是 RVO 的目标(它应该是 make 范围内的临时对象,而不是 make 中与 a 关联的对象).

添加用户提供的复制赋值运算符应该是一种解决方法:

Numbers &operator=(const Numbers &other) { a = other.a; b = other.b; return *this; }

关于c++ - RVO 在返回前覆盖参数中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45866939/

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