Why does this rvalue reference bind to an lvalue?
Asked Answered
C

1

19

I do not understand why the following code compiles on GCC 8.0:

decltype(auto) foo(int&& r) {
    return r;
}

In foo, the declaration type of r is int&&, and so the return type of foo is also int&&. But r itself is an lvalue, and an lvalue cannot bind to an rvalue reference.

Am I missing something?

Claver answered 6/8, 2017 at 12:26 Comment(8)
Reproduced with gcc8, it seems gcc8 deduced the return type to be int&.Tremann
@Tremann They claim the code compiles, so that would be no repro.Overage
@BaummitAugen The fixed code compiles with gcc8, but not clang6.Tremann
@Tremann Now that's more interesting.Overage
@BaummitAugen Yes I'm curious too; I guess it's gcc's bug.Tremann
@Tremann sorry for the confusion; foo should not compile for reasons given in the questionClaver
Seems like a GCC bug indeed. Note however that if you were to return a parenthesized id expression (return (r);, it would work by design).Nebulize
@curiousguy12: As an aside, welcome to StackOverflow. Great first question, we need more people like you around.Leastwise
V
17

According to [dcl.spec.auto]/5, the return type is deduced as if the return statement's operand was the operand of decltype. And [dcl.type.simple]/(4.2) clearly states that, as the operand is not parenthesized, the type of the entity is the type yielded by decltype, that is, int&&. And indeed, r is an lvalue ([expr.prim.id.unqual]).

Fortunately, this has been discovered and filed as bug 64892 two years ago. (I wonder why no one could find the time to fix this?)

Vesicle answered 6/8, 2017 at 14:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.