C++ - 使用 const 引用来延长临时成员,好的还是 UB?

标签 c++ language-lawyer lifetime temporary 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);
}

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

C ctor 56.32 11.99

但是当我用 -O2 编译时,我得到了

 C ctor 0 0

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

const A& a = A();
const B& b = a.b;

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

编辑以供将来引用:

我使用的是 gcc 版本 6.3.0

最佳答案

您的代码应该格式良好,因为对于 temporaries

(强调我的)

Whenever a reference is bound to a temporary or to a subobject thereof, the lifetime of the temporary is extended to match the lifetime of the reference

给定 A().b[4]b[4]b 的子对象和数据成员 b 是 temproray A() 的子对象,其生命周期应该延长。

LIVE on clang10 with -O2
LIVE on gcc10 with -O2

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

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

The third context is when a reference is bound to a temporary object.36 The temporary object to which the reference is bound or the temporary object that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference if the glvalue to which the reference is bound was obtained through one of the following:

...

[ Example:

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

— end example ]

关于C++ - 使用 const 引用来延长临时成员,好的还是 UB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57866023/

相关文章:

c++ - 将绑定(bind)与成员函数结合使用

c++ - SFML 库 : strange error

c++ - 了解 VirtualAlloc 中的基地址

c++ - 我该如何解决这个指针/内存问题?

c - 在一个单词中获取字节地址的最安全的跨平台方法是什么?

rust - 逐字包装辅助函数中的代码会导致借入错误

vector - 无法在新的空向量上设置生命周期

C++1y/C++14 : Assignment to object outside its lifetime is not allowed in a constant expression?

c++ - 没有 <> 的模板特化

rust - 是否可以专注于静态生命周期?