a.lasram
a.lasram

Reputation: 4411

rvalue and lvalue reference with lambda expressions - gcc vs. msvc

In C++, it is illegal to implicitly convert an rvalue to an lvalue reference. Consider the following code where an lvalue reference is bound to an rvalue (the lambda):

int main()
{
    auto& f = []() -> void {};
    return 0;
}

gcc (4.8.1) does not accept such code (makes perfect sense). However, Microsoft compiler does accept it meaning that either it is accepting nonstandard code or C++ allows the particular case where an lvalue reference is bound to an rvalue lambda expression.

The question: which assumption is correct?

Upvotes: 6

Views: 1258

Answers (3)

user1055604
user1055604

Reputation: 1672

To quote Herb Sutter (chair of the ISO C++ standards committee):

A conforming C++ compiler can always allow otherwise-illegal C++ code to compile and give it some meaning — hey, it could choose to allow inline COBOL if some kooky compiler writer was willing to implement that extension, maybe after a few too many Tequilas. For some kinds of extensions the C++ standard requires that the compiler at least emit some diagnostic to say that the code isn’t valid ISO C++, as this compiler does.

He explains further how the following example is illegal:

// Example 2

string f() { return "abc"; }

void g() {
string& s = f();       // illegal?
  cout << s << endl;
}

Please visit this link by Sutter for an explanation, to avoid duplicating the article on SO.

Upvotes: 3

syam
syam

Reputation: 15069

The core of your question is: can rvalues be bound to non-const lvalue references?

The Standard says no. rvalues can only be bound to const lvalue references.

I believe the relevant Standard paragraph is 8.5.3/5:

A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:

...

  • Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be const), or the reference shall be an rvalue reference.

However Microsoft has a long-standing "feature" that allows this non-standard behaviour, which explains what you're witnessing.

Upvotes: 7

Andy Prowl
Andy Prowl

Reputation: 126422

However, Microsoft compiler does accept it meaning that either it is accepting nonstandard code or C++ allows the particular case where an lvalue reference is bound to an rvalue lambda expression.

MSVC is known for having this (not so great) compiler extension. It simply allows binding rvalues to lvalue references to non-const:

A& x = A(); // Illegal in C++, allowed by MSVC

Upvotes: 3

Related Questions