Does Visual Studio not create a temporary object when casting?

I am using Visual Studio Express 2013 and a little cheating when trying to learn about different things in C ++.

I came across an interesting error in the compiler, where it seems that a temporary object is not created when explicitly imposing a listing on the same type as the link.

#include <iostream> using namespace std; int main() { int number; // float number; number = 2; const int& plainref_i = number; const int& recastref_i = (int)number; // this goes wrong if number is int const float& plainref_f = number; const float& recastref_f = (float)number; // this goes wrong if number is float number = 3; std::cout << plainref_i << "\n"; std::cout << recastref_i << "\n"; std::cout << plainref_f << "\n"; std::cout << recastref_f << "\n"; return 0; } 

This, when compiled in VS, leads to the following result: 3 3 2 2

But compiled with gcc leads to the following result: 3 2 2 2

If I replaced "int number"; with "floating point number"; I get to VS: 2 2 3 3

and with gcc: 2 2 3 2

I am wondering if anyone can confirm this as an error, and if anyone knows of a possible workaround / solution.

+7
c ++ casting visual-studio-2013 temporary-objects
source share
1 answer

Given:

  int number; 

The results of this cast should be prvalue:

 const int& recastref_i = (int)number; // this goes wrong if number is int 

and since you are using a reference to a constant, it can bind to the value of prvalue, and its value should be separated from any changes to number , but Visual Studio has an extension that produces lvalue instead of prvalue , so you really get the lvalue reference to number , which means that any changes to the value of number will be reflected when checking the value of recastref_i .

The Visual Studio team recommends using the /Zc:rvalueCast flag to disable this behavior (my attention):

When the / Zc: rvalueCast option is specified, the compiler correctly identifies the rvalue reference type as a result of the 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 switched off. To match and eliminate errors when using throws, we recommend using / Zc: rvalueCast.

unlike /Za , which will disable all extensions that may be problematic in practical scenarios.

From a draft of a standard C ++ 5.4 section 5.4 Explicit text of type conversion (cast notation), which reads (emphasis mine):

The result of expression (T) of the expression expression is of type T. The result is an lvalue if T is a reference type lvalue or rvalue is a reference to the type of the function and the value is x if T is a reference to rvalue to the type of the object; Otherwise, the result will be prvalue.

+3
source share

All Articles