The value of rvalue and lvalue with lambda expressions - gcc vs. msvc

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

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

gcc (4.8.1) does not accept such code (it makes sense). However, the Microsoft compiler does accept this value, meaning that it either accepts non-standard code or C ++ resolves the specific case where the lvalue reference is bound to the rvalue lambda expression.

Question: which assumption is correct?

+4
source share
3 answers

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

The standard states no . rvalues ​​can only be associated with const lvalue references.

I consider the relevant paragraph of Standard 8.5.3 / 5 :

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

...

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

However, Microsoft has a long-standing β€œfeature” that allows non-standard behavior, which explains what you are observing.

+6
source

However, the Microsoft compiler does not agree with this, implying that it either accepts non-standard code or C ++ resolves the specific case where the lvalue reference is bound to the rvalue lambda expression.

MSVC is known for having this (not very large) compiler extension. It just allows you to bind rvalues ​​to lvalue values ​​for non- const :

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

In quote Herb Sutter (chair of the ISO C ++ Standards Committee):

The corresponding C ++ compiler always allows you to compromise different C ++ code and give it some meaning. Hey, he can choose to enable the built-in COBOL if some kooky compiler was ready to implement this extension, maybe after a few too many tequila. For some types of extensions, the C ++ standard requires the compiler to at least emit some diagnostics in order to say that the code does not conform to the C ++ ISO, as the compiler does.

He further explains 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 from Sutter for an explanation to avoid duplicating an article on SO.

+2
source

Source: https://habr.com/ru/post/1486428/


All Articles