对结构成员的临时绑定引用
Temporary bound references to struct members
我在一些代码库上试用 Coverity,我收到了一个类似于
的代码警告
struct Foo
{
std::string name;
};
Foo getFoo();
//...
const auto& name = getFoo().name;
useName(name);
此代码有效吗?
我的直觉确实是无效的。但是后来,在搜索证明时,我遇到了 [class.temporary]/6.4,这似乎表明它实际上是合式的。然而,Coverity 发出警告,Coverity 肯定是由一些比我更能解释标准的聪明人编写的。
发出的具体 Coverity 警告是
Dereferencing the returned or out-of-scope stack pointer will access an invalid location on the stack after its scope or after the function returns.
In whateverSurroundingFunction(): Pointer to a local stack variable returned or used outside scope (CWE-562)
关于 name
的后续 使用 。前面的警告是
out_of_scope: Temporary variable of type Foo
goes out of scope
一种 MRE 是 this(在评论中感谢 @user4581301)。
SO 有很多关于临时绑定引用的问题,但我所看到的每个都有稍微不同的上下文,因此这里又出现了另一个问题。
此代码格式正确。正如链接标准所说,getFoo()
返回的 lifetime of the temporary 将延长到引用变量 name
.
的生命周期
(强调我的)
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
引用直接绑定到临时Foo
的子对象name
,从而延长了生命周期。其他方式,例如通过返回对数据成员的引用的成员函数绑定引用将不起作用。
struct Foo
{
std::string name;
std::string& get_name() { return name; }
};
Foo getFoo();
然后
const auto& name = getFoo().get_name();
std::cout << name << std::endl; // UB; name is dangled
我在一些代码库上试用 Coverity,我收到了一个类似于
的代码警告struct Foo
{
std::string name;
};
Foo getFoo();
//...
const auto& name = getFoo().name;
useName(name);
此代码有效吗?
我的直觉确实是无效的。但是后来,在搜索证明时,我遇到了 [class.temporary]/6.4,这似乎表明它实际上是合式的。然而,Coverity 发出警告,Coverity 肯定是由一些比我更能解释标准的聪明人编写的。
发出的具体 Coverity 警告是
Dereferencing the returned or out-of-scope stack pointer will access an invalid location on the stack after its scope or after the function returns.
In whateverSurroundingFunction(): Pointer to a local stack variable returned or used outside scope (CWE-562)
关于 name
的后续 使用 。前面的警告是
out_of_scope: Temporary variable of type
Foo
goes out of scope
一种 MRE 是 this(在评论中感谢 @user4581301)。
SO 有很多关于临时绑定引用的问题,但我所看到的每个都有稍微不同的上下文,因此这里又出现了另一个问题。
此代码格式正确。正如链接标准所说,getFoo()
返回的 lifetime of the temporary 将延长到引用变量 name
.
(强调我的)
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
引用直接绑定到临时Foo
的子对象name
,从而延长了生命周期。其他方式,例如通过返回对数据成员的引用的成员函数绑定引用将不起作用。
struct Foo
{
std::string name;
std::string& get_name() { return name; }
};
Foo getFoo();
然后
const auto& name = getFoo().get_name();
std::cout << name << std::endl; // UB; name is dangled