Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Let

int a = 0;

Then is (int)a an rvalue in standard C++?

Different compilers show different results for this code:

#include <iostream>
using namespace std;

void f(int& x)
{
    cout << "l value" << endl;
}

void f(int&& x)
{
    cout << "r value" << endl;
}

int main()
{
    int a = 0;
    f((int)a);
}

compilers with different results:

1) http://cpp.sh/2r6

2) http://webcompiler.cloudapp.net/

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
118 views
Welcome To Ask or Share your Answers For Others

1 Answer

The should be an rvalue but webcompiler is running Visual Studio and Visual Studio has an extension which allows temporary objects to be bound to non-const lvalue references. a bug/extension that casues it to generate an lvalue in this case As Igor points out above this can be disabled using /Za (see it live).

We can see that it should be an rvalue(specifically a prvalue) from the draft C++ standard section 5.4 Explicit type conversion (cast notation) paragraph 1 which says (emphasis mine):

The result of the expression (T) cast-expression is of type T. The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type and an xvalue if T is an rvalue reference to object type; otherwise the result is a prvalue.[ Note: if T is a non-class type that is cv-qualified, the cv-qualifiers are ignored when determining the type of the resulting prvalue; see 3.10. —end note ]

Both gcc and clang result in rvalue which is the expected result.

As an aside, I would recommend using rextester over webcompiler since rextester allows you to share your program and also has live sharing.

Update

Ben Voigt point out this bug report and so it seems that Visual Studio actually produces an lvalue. So this is not simply a case of the extension which allows temporary objects to be bound to non-const lvalue references.

As dyp points out gcc used to have a cast to lvalue extension as well.

Update 2

Mgetz filed a bug report, the response was that this is fixed by using the /Zc:rvalueCast flag, the description of the flag is as follows:

When the /Zc:rvalueCast option is specified, the compiler correctly identifies an rvalue reference type as the result of a cast operation in accordance with the C++11 standard. When the option is not specified, the compiler behavior is the same as in Visual Studio 2012. By default, /Zc:rvalueCast is off. For conformance and to eliminate errors in the use of casts, we recommend that you use /Zc:rvalueCast.

It is unclear whether this flag will be enabled by default in future versions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...