Visual Studio is not creating temporary object when typecasting?

吃可爱长大的小学妹 提交于 2019-12-09 11:05:10

问题


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.


回答1:


Given:

 int number;

The results of this cast should be a prvalue:

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

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 to number which means any changes in value to number will be reflected when checking the value of recastref_i.

The Visual Studio team recommends using the /Zc:rvalueCast flag to turn off this behavior (emphasis mine):

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.

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):

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.



来源:https://stackoverflow.com/questions/28402173/visual-studio-is-not-creating-temporary-object-when-typecasting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!