对结构成员的临时绑定引用

Temporary bound references to struct members

本文关键字:绑定 引用 结构 成员      更新时间:2023-10-16

我正在某个代码库上尝试Coverity,我收到了类似于以下内容的代码警告

struct Foo
{
std::string name;
};
Foo getFoo();
//...
const auto& name = getFoo().name;
useName(name);

此代码有效吗?

我直觉它确实是无效的。但是,在搜索证明时,我遇到了[class.temporary]/6.4,它似乎说它实际上是格式良好的。然而,Coverity发出了警告,Coverity肯定是由一些聪明的人编写的,他们比我更能解释标准。

发出的特定覆盖性警告是

取消引用返回或超出范围的堆栈指针将在其作用域之后或函数返回后访问堆栈上的无效位置。

In whateverSurroundingFunction((:指向在作用域外返回或使用的局部堆栈变量的指针 (CWE-562(

关于name后续使用.前面的警告是

out_of_scope:类型Foo的临时变量超出范围

这是一种 MRE(在评论中@user4581301点赞(。


SO 有很多关于临时绑定引用的问题,但我看到的那些每个都有略有不同的上下文,因此这里有另一个关于它们的问题。

此代码格式正确。正如链接标准所说,getFoo()返回的临时的生存期将延长到引用变量name的生存期。

(强调我的(

每当引用绑定到临时对象或其子对象时,临时对象的生存期都会延长以匹配引用的生存期

引用直接绑定到临时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