Validity of presenting an xvalue as an lvalue
Asked Answered
H

1

11

The following function (in my intention) is to take an rvalue and present it as it was an lvalue.

auto constexpr RtoL = [](auto&& r) -> decltype(auto) {
    static_assert(std::is_rvalue_reference_v<decltype(r)>, "Gimme rvalues, not lvalues.");
    return (r);
};

I think of using it in situations where I can guarantee that an xvalue has not been truly moved from (e.g. it was casted to rvalue via std::move, but nothing took advantage of that), so I'd call it with xvalues, not prvalues.

Anyway, compilers (well, versions of GCC) seem to have different opinions on the validity of the code above. Specifically, given this usage:

int main() {
    int x{3};
    RtoL(std::move(x));
}

GCC 11.2 considers it invalid:

<source>:9:14: error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'
    9 |     return (r);
      |              ^

whereas GCC 10.3 and other compilers consider it valid.

Furthermore, changing the return statement from

return (r);

to

return static_cast<decltype(r)&>(r);

makes them all agree that the code is correct.

Where is the truth, from the standard standpoint?

Haemato answered 24/11, 2021 at 8:25 Comment(7)
Gcc seems to have issue with decltype(auto), returning int& works Demo or even auto& Demo.Excavator
Possibly minimal exemplary code with the same issue: int&& r = 1; decltype(auto) rr = (r);. Live demo: godbolt.org/z/jWzEadYsW.Theis
Relevant (possibly duplicate): GCC's decltype(auto) doesn't conform to the standard?.Theis
@DanielLangr, following the like you posted, I could get here, where I read fixed in GCC 11, but the version where I observe the problem is exactly GCC 11.2. Should I deduce that the bug has been reintroduced? Do you suggest filing another report?Haemato
@Haemato I am not a Bugzilla expert, but I guess yes, it seems that the problem has not been fixed as advertized.Theis
Reported.Haemato
Note that C++23 will require the cast (or *&r).Heterosexual
A
2

This was a bug in past versions of GCC (located by commenter @Enlico)

The bug is fixed by GCC version 12.2, but still manifests with GCC 11.3. It will likely be fixed in GCC 11.4 as well.

See this on GodBolt.

Airlike answered 5/2, 2023 at 9:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.