获取返回的临时对象的地址
Taking the address of a returned temporary object
我有一段我认为有效的 C++20 代码,但我们的静态分析器认为它不安全。
struct Foo {
explicit Foo() { activeFoo = this; }
~Foo() { activeFoo = nullptr; }
Foo(const Foo&) = delete;
Foo(Foo&&) = delete;
inline static const Foo* activeFoo = nullptr;
};
Foo makeFoo()
{
// Is there a dangling reference here?
return Foo();
}
int main()
{
auto myFoo = makeFoo();
}
我的静态分析器认为 makeFoo
导致 activeFoo
指向一个临时对象,并将成为一个悬空指针。我认为这是错误的; return Foo();
应该得到一个有保证的复制省略(如删除的复制和移动构造函数所证明的那样),因此只构造了一个 Foo
实例,myFoo
.
谁是正确的?
makeFoo
和复制省略(正如您所指出的,自 C++17 起在这个特定示例中得到保证)甚至都不重要。
activeFoo
永远不能悬空。如果它在其生命周期结束后指向一个对象,那么该对象的析构函数会将 activeFoo
重置为 nullptr
,这意味着它不能指向该对象,这是一个矛盾。这是假设为每个创建的 Foo
类型的对象调用析构函数。从技术上讲,如果您 placement-new 明确反对,情况可能并非总是如此,尽管它应该如此。
然而,我通常不希望静态分析器弄清楚这个逻辑。如果没有关于静态分析器的一些细节或它到底抱怨什么,就很难说更多了。
我有一段我认为有效的 C++20 代码,但我们的静态分析器认为它不安全。
struct Foo {
explicit Foo() { activeFoo = this; }
~Foo() { activeFoo = nullptr; }
Foo(const Foo&) = delete;
Foo(Foo&&) = delete;
inline static const Foo* activeFoo = nullptr;
};
Foo makeFoo()
{
// Is there a dangling reference here?
return Foo();
}
int main()
{
auto myFoo = makeFoo();
}
我的静态分析器认为 makeFoo
导致 activeFoo
指向一个临时对象,并将成为一个悬空指针。我认为这是错误的; return Foo();
应该得到一个有保证的复制省略(如删除的复制和移动构造函数所证明的那样),因此只构造了一个 Foo
实例,myFoo
.
谁是正确的?
makeFoo
和复制省略(正如您所指出的,自 C++17 起在这个特定示例中得到保证)甚至都不重要。
activeFoo
永远不能悬空。如果它在其生命周期结束后指向一个对象,那么该对象的析构函数会将 activeFoo
重置为 nullptr
,这意味着它不能指向该对象,这是一个矛盾。这是假设为每个创建的 Foo
类型的对象调用析构函数。从技术上讲,如果您 placement-new 明确反对,情况可能并非总是如此,尽管它应该如此。
然而,我通常不希望静态分析器弄清楚这个逻辑。如果没有关于静态分析器的一些细节或它到底抱怨什么,就很难说更多了。