Разница между Undefined Поведение и неправильное формирование, не требуется диагностическое сообщение
Стандарт С++ поставляется с потрясающим количеством определений для нечеткого поведения 1 которое означает более или менее то же самое с тонкими различиями. Чтение этого ответа, я заметил, что формулировка "программа плохо сформирована, не требуется диагностика".
Определенный реализацией отличается от неуказанного поведения тем, что реализация в первом случае должна четко документировать, что он делает (в последнем случае это не обязательно), оба они хорошо сформированы. Undefined поведение отличается от неуказанного тем, что программа ошибочна (1.3.13).
В противном случае у всех есть общее, что стандарт не делает никаких предположений или требований относительно того, что будет делать реализация.
За исключением 1.4/8, в котором говорится, что реализации могут иметь расширения, которые не изменяют поведение хорошо сформированных программ, но плохо сформированы в соответствии со стандартом, а реализация должна диагностировать использование этих, но впоследствии может продолжить компиляцию и выполнение плохо сформированной программы.
Программа плохо сформированная иначе определяется как неформальная (отличная!). С другой стороны, хорошо сформированная программа определяется как та, которая придерживается синтаксических и диагностируемых семантических правил. Это, следовательно, означает, что некорректная программа - это та, которая разбивает либо синтаксические, либо семантические правила (или и то, и другое). Другими словами, некорректная программа на самом деле не должна компилироваться вообще (как можно перевести, например, программу с неправильным синтаксисом любым значимым образом?).
Я был бы склонен думать, что слово "ошибочное" также подразумевает, что компилятор должен прервать сборку с сообщением об ошибке (в конце концов, ошибочно предполагает наличие ошибки), но раздел "Примечание" в 1.3.13 явно допускает что-то другое, включая молча игнорирование проблемы (и компиляторы явно не нарушают сборку из-за UB, большинство даже не предупреждают по умолчанию).
Можно также полагать, что ошибочные и плохо сформированные одинаковы, но стандарт не вникает в детали, если это так, или то, что должно означать это слово.
Далее, 1.4 утверждает, что
соответствующая реализация должна [...] принять и правильно выполнить хорошо сформированную программу
и
Если программа содержит нарушение правила, для которого не требуется диагностика, [...] нет требований к реализациям в отношении этой программы.
Другими словами, соответствующая реализация должна принимать хорошо сформированную программу, но она может также принять плохо сформированную и даже без предупреждения. Кроме того, если программа плохо сформирована, потому что она использует расширение.
Во втором абзаце говорится, что что-либо в сочетании с "отсутствием необходимости диагностики" означает, что в спецификации нет требований, что означает, что он в основном эквивалентен "undefined поведению", за исключением того, что упоминание ошибочного не упоминается.
В чем заключалось бы намерение использовать формулировку, такую как "плохо сформированная, не требующая диагностики"?
Наличие "никакой диагностики" предполагает, что оно идентично (или в основном идентично?) поведению undefined. Кроме того, поскольку поведение, определяемое реализацией и неопределенным, определяется как хорошо сформированное, оно должно быть чем-то другим.
С другой стороны, поскольку некорректная программа нарушает синтаксические/семантические правила, она фактически не должна компилироваться. Что, однако, в сочетании с "отсутствием необходимости диагностики" означало бы, что компилятору будет разрешено молча выйти без предупреждения, и после этого вы не сможете найти исполняемый файл.
Есть ли разница между "плохо сформированным, отсутствием диагностики" и "undefined поведением", или это просто сложный синоним для одного и того же?
1 В отсутствие лучшей формулировки для коллективного поведения
Ответы
Ответ 1
Стандарт не всегда согласован, как хотелось бы, поскольку
это очень большой документ, написанный (на практике) числом
разных людей, и, несмотря на все доказательства,
происходит, несоответствия проскальзывают. В случае
undefined (и ошибки вообще), я думаю, что есть
дополнительная проблема в том, что для большинства основных вещей
(указатели и т.д.), стандарт С++ вдохновляет C. Но
C понимает, что все ошибки undefined
поведение, если не указано иное, где в качестве стандарта С++
пытается придерживаться точки зрения, что все ошибки требуют
если не указано иное. (Хотя они все еще
должны учитывать случай, когда стандарт не указывается
поведение.) Я думаю, что это объясняет
несогласованность в формулировке.
В глобальном масштабе несогласованность вызывает сожаление, но в целом, если
в стандарте говорится, что что-то ошибочно или плохо сформировано,
то это требует диагностики, если в стандарте не сказано, что это
не является, или что это поведение undefined. В чем-то вроде
"плохо сформирован, не требуется диагностика", "нет диагностических
требуется ", потому что в противном случае это потребует
диагностика. Что касается разницы между "плохо сформированными", нет
"Требуется диагностика" и "undefined поведение", нет.
Первое, вероятно, более часто встречается в случаях, когда код
неверный, второй, где это проблема во время выполнения, но это не
Систематическое. (Спецификация одного определения
Правило, ясно, что проблема времени компиляции заканчивается на "then
поведение undefined ".)
Ответ 2
Как это должно быть: вещи, которые undefined, не вызывают проблем, если конкретный запуск программы не вызывает поведение undefined. Например. разыменование нулевого указателя только разрушает ваш день, когда ваша конкретная программа запускается (характеризуется ее вводом: ввод-вывод, не детерминированные функции, такие как часовые запросы и т.д.), фактически выполняет ее, но она обращается в обратном направлении, поэтому она может отображать undefined даже до тех пор, пока технически не достигнет разыменования. (Это в основном там, где я могу подумать о перестановках кода.)
В то время как плохо сформированный НДР является тем, что реализация должна диагностировать во время перевода, но может быть неспособна из-за различных технических или теоретических ограничений. Например. ODR потребует, чтобы реализация собирала все определения сущности и сравнивала их; но что массивный ресурс истощается. Некоторые вещи NDR даже вычислительно неосуществимы. undefined поведение возникает, когда реализация не сразу диагностирует этот материал.
На практике поведение undefined применяется к некоторым странным случаям, которые не являются условиями выполнения. Некоторые странные проблемы с препроцессором вызывают поведение undefined. Это странно, потому что они не имеют значимого представления в скомпилированной программе, поэтому неясно, что может заставить их выполнить.
Тем не менее, этот взгляд по-прежнему дает вам разумную идею о том, почему существуют два термина.