Неконстантная ссылка, связанная с временной ошибкой Visual Studio?

Я столкнулся с этим при компиляции переносимого кода в gcc. По сути, этот странный код компилируется в Visual Studio, что просто поражает меня:

class Zebra {int x;};
Zebra goo() {Zebra z; return z;}
void foo(Zebra &x)
{
    Zebra y;
    x = y;
    foo(goo());
}

Visual studio позволяет этому летать. gcc поймает это как ошибку компиляции. Интересно, что если вы введете определение Zebra в int, VC++ будет жаловаться. Довольно противоречивое поведение. Мысли?


person user805547    schedule 05.05.2013    source источник
comment
Это не ошибка, это расширение компилятора, причем злое.   -  person chris    schedule 05.05.2013
comment
У MSVC есть warning C4239: nonstandard extension used, но, видимо, у вас отключено это предупреждение.   -  person MSalters    schedule 06.05.2013
comment
Я не понимаю, почему вам понадобилось использовать бесконечно рекурсивную функцию для демонстрации этого.   -  person Neutrino    schedule 24.11.2016


Ответы (2)


Это старое расширение для Visual Studio, единственная ссылка, которую я смог найти на сайте Microsoft, это отчет об ошибке: Временные объекты могут быть привязаны к неконстантным ссылкам, который имеет следующий пример кода:

struct A {};

A     f1();
void f2(A&);

int main()
{
    f2(f1()); // This line SHALL trigger an error, but it can be compiled without any     errors or warnings.
}

В одном из ответов отмечается:

Существует предупреждение уровня 4 (предупреждение уровня 4 включается, если вы передаете /W4 компилятору) для него

Этот пост в блоге: Visual C++ настолько либерален, который охватывает это расширение, отмечает, что:

Использование Disable Language Extensions (/Za) приводит к ошибке:

person Shafik Yaghmour    schedule 31.12.2013

Как говорили другие, это связано с расширением Microsoft C++. Хотя флаг /Za не рекомендуется, так как он может сломать что-то.

Вместо этого используйте переключатель /permissive- для лучшего соответствия стандартам, и вы получите здоровые ошибки для этих случаев. Обратите внимание, что этот флаг доступен с VS 2017.

Параметр /Za не поддерживает некоторые ключевые заголовочные файлы Microsoft SDK. Напротив, /permissive- предлагает полезный режим соответствия, в котором входной код C++ интерпретируется в соответствии с правилами ISO C++, но также позволяет согласовывать расширения, необходимые для компиляции C++ на целевых объектах, поддерживаемых Visual C++.

Дополнительные сведения см. в блоге группы Visual C++.

person Onur Gumus    schedule 23.10.2017
comment
Вероятно, стоит отметить, что флаг /permissive доступен с VS 2017. Вы можете улучшить этот ответ, включив соответствующие цитаты из статьи. Например, что он делает, почему был введен и его связь с /Za - person bolov; 23.10.2017