Is an xvalue's lifetime extended when it is bound to a const lvalue reference?

旧时模样 提交于 2019-12-30 08:25:10

问题


If I write the following code:

#include <iostream>

using namespace std;

int main()
{
  cout << &(int &&)123 << endl;
  return 0;
}

Then g++ complains:

foo.cc: In function ‘int main()’:
foo.cc:7:20: error: taking address of xvalue (rvalue reference)

Ok, thanks to What are rvalues, lvalues, xvalues, glvalues, and prvalues? I get that an xvalue means that it's about to "expire", which makes sense. But now if I do this:

#include <iostream>

using namespace std;

int main()
{
  const int &x = (int &&)123;
  cout << &x << endl;
  return 0;
}

This "works" just fine and will print an address. So, I have a few questions:

  1. If the value is about to expire, why can I make a reference to it? The reference won't keep the original object alive (right?).
  2. Does such a reference result in undefined behavior? E.g. because we're referencing an object that may have been destroyed?

In general is there a way to know the lifetime of an rvalue reference?


回答1:


Clause 12.2, paragraphs 4-5, says that the lifetime is extended in the second example

There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression. ...

The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
(none of the exceptions apply here)




回答2:


Perhaps I'm alone but I think that this is not safe:

const int &x = (int &&)123;

The lifetime-lengthening rules apply only when the reference is initialized by an expression that directly refers to a temporary object. In other words, the expression has to carry the "temporary" attribute. If you omit the (int&&), then for binding to the reference, the compiler will implicitly create a prvalue expression that refers to a temporary object which is initialized by the value 123 and lifetime lengthening then applies.

But if you mix rvalue references in between, the compiler has no way to know at compile time whether or not to lengthen the lifetime of the referred-to object.

int a = 0;
const int &x = ((rand() == 42) ? (int&&)123 : (int&&)a);

I therefor think that your code has undefined behavior, because you evaluate a dangling reference (even if only for taking its address).



来源:https://stackoverflow.com/questions/9467872/is-an-xvalues-lifetime-extended-when-it-is-bound-to-a-const-lvalue-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!