【问题标题】:How to activate (N)RVO for aggregates in Visual Studio?如何在 Visual Studio 中为聚合激活 (N)RVO?
【发布时间】:2018-07-20 23:09:57
【问题描述】:

Visual C++ 是否支持(命名的)聚合返回值优化 (N)RVO?

示例如下:

struct Vector
{
    float data[100];
};

void print(const Vector & v);

inline Vector makeVector()
{
    Vector c;
    return c;
}

void foo()
{
    print(makeVector());
}

经过优化编译(/O2 开关) https://godbolt.org/g/bb8HZj 可以很容易地看到 makeVector() 函数中构造的 Vector 的复制

    lea      rcx, QWORD PTR [rcx+128]
    movups   xmm0, XMMWORD PTR [rax]
    lea      rax, QWORD PTR [rax+128]
    movups   XMMWORD PTR [rcx-128], xmm0
    movups   xmm1, XMMWORD PTR [rax-112]
    movups   XMMWORD PTR [rcx-112], xmm1
    movups   xmm0, XMMWORD PTR [rax-96]
    movups   XMMWORD PTR [rcx-96], xmm0
    ...

很明显,这里没有像其他编译器那样的 NRVO。有没有办法在 Visual C++ 中打开或激活它?

【问题讨论】:

    标签: c++ visual-studio return-value-optimization


    【解决方案1】:

    看起来 MSVC 不会将 RVO 应用于被视为 C 结构的类型。解决方案是让您的 Vector 看起来像 C++ 类型(使其成为非 POD,但我不确定 POD 是否是 MSVC 在这里使用的)。试试这个:

    struct Vector
    {
        Vector() { }
    
        float data[100];
    };
    

    小心,因为它会改变语义:您将无法使用 Vector v{} 对其进行零初始化。

    【讨论】:

    • 您基本上建议将Vector 设为非聚合。而且您正确地说您的版本不会默认初始化data 为零。要使Vector 不聚合并保持其默认初始化,必须将构造函数定义如下:Vector() : data{} {}。演示:godbolt.org/z/xc5b9G8M3
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 2022-11-02
    相关资源
    最近更新 更多