Подтвердить что ты не робот

Указывает ли стандарт С++, что в некоторых случаях компиляция должна завершиться с ошибкой?

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

[Примечание. Как указано выше, такие преобразования не допускаются на верхнем уровне в инициализации списка. - конечная нота]

Я думаю, что описание "не разрешено" означает, что компиляция должна завершиться неудачей.

Но кто-то сказал мне, что здесь просто говорит, что "программа плохо сформирована", и стандарт не требует, чтобы компиляция должна потерпеть неудачу.

если требуется преобразование сужения (см. ниже) для преобразования элемент в T, программа плохо сформирована.

Итак, мой вопрос: определяет ли стандарт, следует ли генерировать ошибку или предупреждение? Или в некоторых случаях компиляция должна завершиться неудачей? С точки зрения компилятора, хорошо ли сделать компиляцию программы и просто дать некоторые предупреждения?

BTW: Clang 4.0.0 и Gcc 7.0.0 ведут себя по-другому.

float a {1.e39}; // Error for both Clang and GCC
double d;
float a3{d};     // Error for Clang, warning for GCC
4b9b3361

Ответ 1

Стандарт не использует термины "ошибка" и "предупреждение", он говорит только о случаях, когда компилятор должен "выдать диагностику".

В вашем примере, если программа "плохо сформирована", компилятор должен сказать вам, что каким-то образом вывести диагностику.

После этого он может делать все, что ему нравится, включая компиляцию и запуск программы в любом случае. В стандарте указывается только то, что происходит для соответствующего кода, а все остальное - undefined. И тогда, как мы знаем, все может случиться.

Ответ 2

Единственным требованием для плохо сформированной программы является то, что компилятор должен "выдать диагностику", где "диагностика" имеет значение, определенное реализацией. Сделав это, компилятор может продолжить компиляцию кода. Это основной крючок для поведения, специфичного для реализации.

Ответ 3

Если программа не является плохо сформированной, компилятор должен выдавать исполняемый файл. Если программа не содержит UB, исполняемый файл должен вести себя как абстрактная машина, стандарт описывает состояния, которые он будет вести. Если он содержит UB, исполняемый файл может сделать что угодно.

Если программа плохо сформирована без необходимости диагностики, компилятор может сделать что угодно. Он может выдавать исполняемый файл, или нет. Этот исполняемый файл может вообще что-то сделать. Он мог бы разработать программу, которая, по-видимому, соответствует намерению кода, например.

Составители могут печатать диагностику, когда захотят.

В некоторых ситуациях компиляторы должны печатать диагностику. "Большинство" плохо сформированных программ требуют диагностики. Какая диагностика - это точно определенная реализация. Было отмечено, что печать единственной пустой новой строки или пробела является допустимой диагностикой по стандарту.

Это будет считаться низким качеством реализации.

Как только диагностика печатается, когда есть некорректная программа, требующая диагностики, компилятор может свободно что-либо делать. Он может создавать исполняемый файл, который несколько соответствует тому, что вы просите, создает исполняемый файл, который делает все, что он хочет, или не создает исполняемый файл.

В стандарте нет различий между предупреждениями и ошибками.

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

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

Неправильная программа, не требующая диагностики, может распечатать диагностику. Он может выбрать создание исполняемого файла или нет. Исполняемый может сделать что-то разумное или нет.

Хорошо сформированная программа может иметь компилятор, выдающий диагностику. Эта диагностика может быть описана как предупреждение. Его также можно описать как ошибку, но компилятор должен создать исполняемый файл, а исполняемый файл должен выполнять стандартные мандаты.

Ответ 4

Если программа не плохо сформирована (и не имеет UB), компилятор должен произвести исполняемый вывод. Если программа плохо сформирована, стандарт не создает ограничение на выход или нет.

Если программа плохо сформирована, и это не NDR, диагностика должна быть производится. В стандарте не проводится различие между предупреждениями или ошибками.

Ответ 5

Примечания в стандарте являются ненормативными и не влияют на определение языка. Таким образом, примечание в вашей первой цитате не важно с точки зрения адвоката языка.

Сказав это, я думаю, что обе ваши цитаты означают одно и то же. "Плохо сформированная программа" - это та, которая не построена в соответствии с правилами синтаксиса, диагностическими семантическими правилами и одним правилом определения стандартного (акцент мой). Если определенная семантика "не допускается", это просто означает, что она нарушает диагностируемое семантическое правило langugae, и поэтому просто означает, что он плохо сформирован.

Компилятор должен выдать диагностику для плохо сформированной программы. После этого компилятор может делать все, что захочет. В стандарте не указаны условия, при которых компиляция должна завершиться неудачей.