3

From 5.2.1.1:

The expression E1[E2] is identical (by definition) to *((E1)+(E2)) [...] except that in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise.

However, with the code below:

struct S { int arr[5]; }; int main() { int &&r = S().arr[0]; } 

both GCC and Clang complain about "rvalue reference cannot bind to lvalue int".

What have I misunderstood? As I understand S() is rvalue, S().arr is xvalue, so S().arr[0] should be xvalue as well and should be able to bind to rvalue refs.

10
  • @Someprogrammerdude I'm pretty sure it does, cf. the for(auto &&r : c) pattern that also works for std::vector<bool>. Edit: it does indeed. Commented Mar 12, 2017 at 17:32
  • 2
    @Someprogrammerdude rvalue references absolutely prolong lifetimes. Commented Mar 12, 2017 at 17:32
  • (rvalue) references prolong lifetimes, but only when a temporary value is assigned to them. In this case arr[0] returns a reference and the value is an array element, of an array which is a member variable of a temporary. So in this case r absolutely does dangle, just not for the reasons originally mentioned. So OP: while this is a compiler bug, this code is still a terrible idea. Commented Mar 12, 2017 at 17:37
  • 1
    @NirFriedman No, r would prolong the lifetime of S(): "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" Commented Mar 12, 2017 at 17:39
  • @Barry No, you are incorrect. I don't know what else to say. Lifetime extension is not transitive. S is never assigned to a reference, so why would its lifetime be extended? Working example (had to change to const ref, because coliru's clang/gcc versions have the bug): coliru.stacked-crooked.com/a/c8f585b116449088. Commented Mar 12, 2017 at 17:42

1 Answer 1

5

You are correct, for the reason you cite. S().arr[0] is an xvalue as of DR 1213, so you should be able to bind an rvalue reference to it.

This is gcc bug 79832. Note that clang HEAD compiles this fine.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.