C ++-使用const引用来延长临时成员,确定成员或UB成员?

use*_*954 37 c++ temporary lifetime language-lawyer reference-binding

考虑这样的事情:

#include <iostream>

struct C {
    C(double x=0, double y=0): x(x) , y(y) {
        std::cout << "C ctor " << x << " " <<y << " "  << "\n";
    }
    double x, y;
};

struct B {
    B(double x=0, double y=0): x(x), y(y) {}
    double x, y;
};

struct A {
    B b[12];

    A() {
        b[2] = B(2.5, 14);
        b[4] = B(56.32,11.99);
    }
};


int main() {
    const B& b = A().b[4];
    C c(b.x, b.y);
}
Run Code Online (Sandbox Code Playgroud)

当我用-O0编译时,我得到了打印

C ctor 56.32 11.99
Run Code Online (Sandbox Code Playgroud)

但是当我用-O2编译时

 C ctor 0 0
Run Code Online (Sandbox Code Playgroud)

我知道我们可以使用const引用来延长本地临时时间,所以类似

const A& a = A();
const B& b = a.b;
Run Code Online (Sandbox Code Playgroud)

完全合法。但我正在努力寻找为什么相同的机制/规则不适用于任何临时形式的原因

编辑以备将来参考:

我正在使用gcc版本6.3.0

son*_*yao 33

您的代码应格式正确,因为对于临时用户

(强调我的)

每当引用绑定到临时对象或其子对象时,临时对象的生存期都会延长以匹配引用的生存期

给定A().b[4]b[4]是的子对象b和数据成员b是temproray的子对象A(),它的寿命应延长。

在带有-O2的clang10 上直播在带有-O2的
gcc10上直播

顺便说一句:这似乎是gcc的错误,已修复。

根据标准,[class.temporary] / 6

第三种情况是引用绑定到临时对象时。36如果通过以下方式之一获得引用所绑定的glvalue,则引用所绑定的临时对象或作为引用所绑定的子对象的完整对象的临时对象在引用的生存期内将持续存在。以下:

...

[示例:

template<typename T> using id = T;

int i = 1;
int&& a = id<int[3]>{1, 2, 3}[i];          // temporary array has same lifetime as a
const int& b = static_cast<const int&>(0); // temporary int has same lifetime as b
int&& c = cond ? id<int[3]>{1, 2, 3}[i] : static_cast<int&&>(0);
                                           // exactly one of the two temporaries is lifetime-extended
Run Code Online (Sandbox Code Playgroud)

—结束示例]

  • @ user2717954我想我找到了[it](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81420)。 (2认同)