[英]Temporary bound references to struct members
I was trying Coverity out on some code base and I got a warning on a code akin to我在一些代码库上尝试使用 Coverity,但我收到了类似于代码的警告
struct Foo
{
std::string name;
};
Foo getFoo();
//...
const auto& name = getFoo().name;
useName(name);
Is this code valid?此代码有效吗?
I had the intuition that it's indeed invalid.我的直觉是它确实是无效的。 But then, when searching for proofs, I've come across [class.temporary]/6.4 , which seems to say that it's actually well-formed.
但是,在搜索证明时,我遇到了[class.temporary]/6.4 ,这似乎说它实际上是格式正确的。 Yet, Coverity issues a warning, and Coverity is surely written by some smart folks that can interpret the standard better than me.
然而,Coverity 发出警告,Coverity 肯定是由一些比我能更好地解释标准的聪明人编写的。
The specific Coverity warning that's issued is发出的具体 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.
取消引用返回的或超出范围的堆栈指针将在其 scope 或 function 返回之后访问堆栈上的无效位置。
In whateverSurroundingFunction(): Pointer to a local stack variable returned or used outside scope (CWE-562)
在whateverSurroundingFunction()中:指向在scope(CWE-562)之外返回或使用的局部堆栈变量的指针
on the subsequent usage of name
.关于
name
的后续用法。 The preceding warning is that前面的警告是
out_of_scope: Temporary variable of type
Foo
goes out of scopeout_of_scope:
Foo
类型的临时变量超出 scope
And a sort of MRE is this (kudos to @user4581301 in the comments).这是一种 MRE(在评论中对 @user4581301 表示敬意)。
SO has a bunch of questions about temporary bound references, but those that I've seen each has a slightly different context, hence here comes yet another question on them. SO 有很多关于临时绑定引用的问题,但我见过的每个问题的上下文都略有不同,因此这里还有一个关于它们的问题。
This code is well-formed.这段代码格式正确。 As the linked standard says, the lifetime of the temporary returned by
getFoo()
will be extended to the lifetime of the reference variable name
.正如链接标准所说,
getFoo()
返回的临时变量的生命周期将延长到引用变量name
的生命周期。
(emphasis mine) (强调我的)
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
每当引用绑定到临时对象或其子对象时,临时对象的生命周期就会延长以匹配引用的生命周期
The reference is bound to the subobject name
of the temporary Foo
directly, then the lifetime gets extended.引用直接绑定到临时
Foo
的子对象name
,然后生命周期得到延长。 Other ways, eg binding the reference via the member function returning reference to data member won't work.其他方式,例如通过成员 function 绑定引用返回对数据成员的引用将不起作用。
struct Foo
{
std::string name;
std::string& get_name() { return name; }
};
Foo getFoo();
then然后
const auto& name = getFoo().get_name();
std::cout << name << std::endl; // UB; name is dangled
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.