Почему это сужающее преобразование не обнаружено? - PullRequest
15 голосов
/ 19 июня 2019

при построении переменных с использованием инициализации списка (например, int x{ 5 };) стандарт §8.5.4 гласит:

Если требуется сужающее преобразование […] дляпреобразовать любой из аргументов, программа является плохо сформированной. (7) Сужающее преобразование - это неявное преобразование - (7.4) из целочисленного типа или перечислимого типа с незаданной областью в целочисленный тип, который не может представлять все значения исходного типа, кромегде источник - это константное выражение, значение которого после интегральных повышений будет соответствовать целевому типу.

Так почему этот компилятор?

char c{ 'A' };
char x{ c + c };

В качестве напоминания, c + c дает int

static_assert(std::is_same_v<decltype(c + c), int>, "");

, поэтомукомпилятор должен жаловаться на сужающее преобразование, которое, конечно, не является константным выражением.


Интересно, что объявление x как unsigned char правильно не компилируется:

char c{ 'A' };
unsigned char x{ c + c }; 

C2397 преобразование из 'int' в 'unsigned char' требует сужающего преобразования

Как и введение временного:

char c{ 'A' };
int sum{ c + c };
char x{ sum }; //C2397 conversion from 'int' to 'char' requires [...]

Так почему первыйверсия компилируется?Я использую Visual Studio Community 2017 версии 15.9.5 и компилирую ее с /wall, и все предупреждения включены в отладочную сборку x64.Установка стандарта C ++ 11, C ++ 14 и C ++ 17 - все компилируется.


Я подал отчет об ошибке здесь

1 Ответ

11 голосов
/ 19 июня 2019

Да.Вы правы: программа плохо сформирована .

В таком случае ( стандарт §1.4 ):

соответствуетреализация должна выдать хотя бы одно диагностическое сообщение.

Действительно, gcc выдает предупреждающее сообщение.clang прямо отклоняет код как ошибку компилятора.

Эта конкретная тема уже обсуждалась здесь для gcc 1 .

Visual Studio должен выдавать диагностическое сообщение (предлагаю проверить параметры компиляции. Вы отключили предупреждения? Компилируете ли вы с C ++ (11/14/17) ?, ...).Если это не так, это ошибка реализации.

Обновление:

Visual Studio v19.20 не выдает диагностическое сообщение (даже с флагом /Wall).

Отчет об ошибке был заполнен здесь.


1 Для получения дополнительной информацииотносительно реализации gcc для проверки сужения здесь .

...