Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behavior in GCC: rvalue ref and lvalue ref are covariant return types

I have this little piece of code:

struct Res { };

struct A {
    virtual Res &&foo();
};

struct B : A {
    Res &foo() override;
};

It compiles in GCC, but not in Clang: https://godbolt.org/z/65rffW .

According to the standard language quoted here, the lvalue reference is not a covariant return type for an rvalue reference.

Why doesn't GCC issue an error?

like image 795
user26785 Avatar asked Mar 18 '21 19:03

user26785


People also ask

What is the difference between an rvalue and an lvalue reference?

Now an lvalue reference is a reference that binds to an lvalue. lvalue references are marked with one ampersand (&). And an rvalue reference is a reference that binds to an rvalue. rvalue references are marked with two ampersands (&&).

Can lvalue const references bind to rvalues?

I mentioned that lvalue const references could bind to rvalues: void f (MyClass const& x) { ... } but they are const, so even though they can bind to a temporary unnamed object that no one cares about, f can’t modify it.

What is covariant return types HackerRank solution in Java?

Hello coders, today we are going to solve Covariant Return Types HackerRank Solution in Java. Java allows for Covariant Return Types, which means you can vary your return type as long you are returning a subclass of your specified return type.

What is an R-value in C++?

“r-value” refers to the data value that is stored at some address in memory. References in C++ are nothing but the alternative to the already existing variable. They are declared using the ‘&’ before the name of the variable.


1 Answers

This was actually the subject of a standard defect report, a quite old one:

  1. Covariant functions and lvalue/rvalue references Section: 11.7.3 [class.virtual] Status: CD2 Submitter: James Widman Date: 1 September, 2009

[Voted into WP at March, 2010 meeting.]

11.7.3 [class.virtual] paragraph 5 requires that covariant return types be either both pointers or both references, but it does not specify that references must be both lvalue references or both rvalue references. Presumably this is an oversight.

Proposed resolution (February, 2010):

Change 11.7.3 [class.virtual] paragraph 5 bullet 1 as follows:

...If a function D::f overrides a function B::f, the return types of the functions are covariant if they satisfy the following criteria:

  • both are pointers to classes, both are lvalue references to classes, or both are rvalue references to classes106

...

From http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#960


The code is undoubtedly ill-formed, Clang and MSVC (at least) did address the issue whereas GCC did not.

I filed a bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99664


Update:

The bug was fixed, test case here. Will be included in gcc 12.

like image 151
anastaciu Avatar answered Nov 10 '22 07:11

anastaciu