【问题标题】:Am I testing the Return Value Optimization correctly?我是否正确测试了返回值优化?
【发布时间】:2020-05-08 08:07:24
【问题描述】:

考虑:

struct Measures {
    char name[128]; // added in response to comments
    int   age;
    float weight;
};

Measures foo() {
    Measures res;
    cout << &res << endl;
    return res;
}

int main() {
    Measures m = foo();
    cout << &m << endl;
    system("pause");
    return 0;
}

我在 Visual Studio 中运行这段代码得到的输出是:

004FFA30
004FFB28

我是否从两个地址不同的事实得出正确的结论,即未执行返回值优化?如果是这样,为什么在这种情况下不执行(我发现几个处理 Visual Studio 2017(版本 15.9.14)的帖子没有执行返回值优化,但似乎都不是关于这种特殊情况的)?

【问题讨论】:

  • 哪个版本的虚拟工作室?
  • 您是在测试调试版本还是发布(优化)版本?
  • 您可能会看到这个stackoverflow.com/questions/48879226/… - 尝试将char b[128]; 成员添加到您的结构中。它肯定不适合寄存器,所以你会知道是否是这种情况。
  • 这是 NRVO,不是普通的 RVO。
  • @StoryTeller-UnslanderMonica 我做到了。输出中的地址仍然不同。

标签: c++ return-value-optimization


【解决方案1】:

https://godbolt.org/z/FCRtY9

正如 cmets 中所暗示的,这与结构的大小有关。如果结构适合寄存器,那么地址可能会改变。

创建更大的结构后,地址保持不变。

请注意,保证会发生复制省略:https://stackoverflow.com/a/48881336/461597

#include <iostream>
using std::cout;
using std::endl;

struct Measures {
    int   age;
    float weight;
};

struct BigMeasures {
    Measures m;
    int foo, bar, moo, mar;
};

Measures foo() {
    Measures res;
    cout << &res << endl;
    return res;
}

BigMeasures bar() {
    BigMeasures res;
    std::cout << &res << "\n";
    return res;
}

int main() {
    std::cout << "Small Measures:\n";
    Measures m = foo();
    cout << &m << endl;
    std::cout << "Big Measures:\n";
    BigMeasures bm = bar();
    std::cout << &bm << "\n";
    return 0;
}

【讨论】:

  • 我更改了更新问题中所示的代码,但仍然看到不同的地址。
  • godbolt.org/z/o85yao 这也是与 MSVC 的比较。添加 char 数组会导致 Clang 打印相同的地址。但我无法在 Windows 上对此进行评估。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
  • 2011-08-04
相关资源
最近更新 更多