I'm using Visual Studio Express 2013 and is fooling around a bit trying to learn about different things in C++.
I stumbled upon an interesting bug in the compiler where it doesn't seem to create a temporary object when explicitly type casting to the same type as the reference.
#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 will when compiled in VS, results in the following output: 3 3 2 2
But compiled with gcc, results in the following output: 3 2 2 2
If I replace "int number;" with "float number;" I get in VS: 2 2 3 3
and with gcc: 2 2 3 2
I'm wondering if anyone can confirm this as a bug and if anyone knows of a feasible workaround/solution.
Given:
The results of this cast should be a prvalue:
and since you are using const reference then it can bind to the prvalue and its value should be divorced from any changes to
number
but Visual Studio has an extension which produces an lvalue instead of a prvalue, so you actually receive an lvalue reference tonumber
which means any changes in value tonumber
will be reflected when checking the value ofrecastref_i
.The Visual Studio team recommends using the
/Zc:rvalueCast
flag to turn off this behavior (emphasis mine):as opposed to
/Za
which will disable all extensions which can be problematic in practical scenarios.From the draft C++ standard section
5.4
Explicit type conversion (cast notation) paragraph 1 which says (emphasis mine):