临时对象的哪些操作可以防止其寿命延长?

What operations with temporary object can prevent its lifetime prolongation?

如您所知,在 C++ 中,如果临时对象绑定到本地引用,则临时对象的生命周期会延长到范围结束。

但是如果用临时或其他操作执行强制转换会发生什么,例如:

#include <iostream>

struct S
{
    virtual ~S() { std::cout << "~S() "; }
};

struct U : S {};

int main() 
{
    // this temporary is destroyed in this line in GCC, and at the end in Clang
    [[maybe_unused]] auto && u = dynamic_cast<const U&>( static_cast<const S&>( U{} ) );
    std::cout << ". ";
    // this temporary is destroyed in this line in Clang, and at the end in GCC
    [[maybe_unused]] auto && s =  *&static_cast<const S&>( S{} );
    std::cout << ". ";
}

这里很明显us都引用了对应的临时对象,但Clang和GCC只延长了其中一个临时对象的生命周期,并没有就哪个临时对象达成一致:https://gcc.godbolt.org/z/onWKaq8MG

两个编译器都在他们的权利范围内,还是其中一个(或两个)编译器的行为不正确?

我认为 Clang 是正确的。

第一种情况的lifetime of the temporary应该延长

  • a const_cast, static_cast, dynamic_cast, or reinterpret_cast conversion without a user-defined conversion that converts one of these expressions to the glvalue refers to the object designated by the operand, or to its complete object or a subobject thereof (an explicit cast expression is interpreted as a sequence of these casts),

这里没有自定义转换,应该延长生命周期。

对于第二种情况,表达式*&...不包括在延长生命周期的情况下,临时应在完整表达式后立即销毁。

顺便说一句:Gcc 似乎仅在 dynamic_cast 时表现不同。将第一种情况下的 dynamic_cast 更改为 static_castreinterpret_cast,或者延长 c 风格的转换生命周期。