临时对象的哪些操作可以防止其寿命延长?
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 << ". ";
}
这里很明显u
和s
都引用了对应的临时对象,但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_cast
、reinterpret_cast
,或者延长 c 风格的转换生命周期。
如您所知,在 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 << ". ";
}
这里很明显u
和s
都引用了对应的临时对象,但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_cast
、reinterpret_cast
,或者延长 c 风格的转换生命周期。