Visual Studio не создает временный объект при приведении типов?

Я использую Visual Studio Express 2013 и немного дурачусь, пытаясь узнать о разных вещах в C ++.

Я наткнулся на интересную ошибку в компиляторе, когда кажется, что он не создает временный объект при явном приведении типов к тому же типу, что и ссылка.

#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;
}

Это будет при компиляции в VS, приведет к следующему выводу:
3
3
2
2

Но скомпилированный с gcc, приводит к следующему выводу:
3
2
2
2

Если я заменю «int number;» с «числом с плавающей точкой»; Я получаю в VS:
2
2
3
3

и с gcc:
2
2
3
2

Мне интересно, может ли кто-нибудь подтвердить это как ошибку и знает ли кто-нибудь о возможном обходном пути / решении.

7

Решение

Дано:

 int number;

Результаты этого броска должны быть prvalue:

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

и поскольку вы используете константную ссылку, то она может привязываться к prvalue, и ее значение должно быть отделено от любых изменений в number но Visual Studio имеет расширение, которое производит lvalue вместо prvalue, так что вы на самом деле получите ссылку на lvalue number что означает любые изменения в стоимости number будет отражено при проверке значения recastref_i,

Команда Visual Studio рекомендует использовать /Zc:rvalueCast флаг, чтобы отключить это поведение (акцент мой):

Когда указана опция / Zc: rvalueCast, компилятор корректно
идентифицирует ссылочный тип rvalue как результат операции приведения
в соответствии со стандартом C ++ 11. Когда опция не
указано, поведение компилятора такое же, как в Visual Studio 2012.
По умолчанию / Zc: rvalueCast отключен. Для соответствия и устранения
ошибки в использовании приведений, мы рекомендуем использовать / Zc: rvalueCast.

в отличие от /Za который отключит все расширения, которые может быть проблематичным в практических сценариях.

Из проекта стандартного раздела C ++ 5.4 Явное преобразование типов (нотация приведения) параграф 1 который говорит (акцент мой):

Результат выражения (T) cast-expression имеет тип T.
результатом является lvalue, если T является ссылочным типом lvalue или rvalue
ссылка на тип функции и значение xvalue, если T является ссылкой rvalue
типу объекта; в противном случае результат является prvalue.

3

Другие решения