简体   繁体   English

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

[英]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 scope out_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

LIVE居住

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM