【问题标题】:What operations with temporary object can prevent its lifetime prolongation?对临时对象进行哪些操作可以防止其寿命延长?
【发布时间】:2021-09-27 17:25:39
【问题描述】:

正如您在 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

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

【问题讨论】:

    标签: c++ object-lifetime temporary-objects


    【解决方案1】:

    我认为 Clang 是正确的。

    第一种情况下的lifetime of the temporary 应该被扩展。

    • 没有用户定义转换的 const_cast、static_cast、dynamic_cast 或 reinterpret_cast 转换将这些表达式之一转换为泛左值是指操作数指定的对象,或其完整对象或其子对象(显式转换表达式被解释为这些类型转换的序列),

    这里没有发生用户定义的转换,应该延长生命周期。

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

    顺便说一句:Gcc 似乎只与 dynamic_cast 表现不同。将第一种情况下的 dynamic_cast 更改为 static_castreinterpret_cast 或 c 样式的转换生命周期得到延长。

    【讨论】:

    猜你喜欢
    • 2011-11-26
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 2022-10-14
    相关资源
    最近更新 更多