Что означает [Примечание] в параграфе неопределенного поведения в стандарте C ++? - PullRequest
1 голос
/ 25 ноября 2010

Как пользователь Тони указывает на в параграфе 1.3.12 стандарта C ++ есть [Примечание] высказывание

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

Разве это не противоречит определению UB, говорящему, что ... этот международный стандарт не предъявляет никаких требований ?Я имею в виду, что они говорят «нет требований», а затем говорят «допустимый UB» - прямо в том же параграфе.

Как следует толковать эту записку?Это действительно ограничивает UB в любом случае?

Ответы [ 3 ]

7 голосов
/ 25 ноября 2010

Из §6.5.1 Часть 3 Директив ISO / IEC:

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

Так что это совершенно ненормативно (необязательно) и предназначено только для возможного разъяснения.

6 голосов
/ 25 ноября 2010

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

2 голосов
/ 13 декабря 2010

В этой заметке объясняется, что может сделать реализация, если она встречает код, для которого нет определенного поведения. Слово «допустимый» не предназначено для ограничения, скорее приведены некоторые примеры общего поведения.

Интересно отметить, что компилятор почти всегда должен что-то компилировать! Рассмотрим этот фрагмент кода:

void f() { 1 / 0; }

поведение переводчика при столкновении с этим не очень хорошо определено, но он не может просто делать то, что ему нравится! Фактически, если это компилятор, он все равно необходим для компиляции этого модуля компиляции. Это потому, что поведение программы, содержащей эту функцию, все еще может быть четко определено! Компилятор не может знать, вызвана ли функция. Фактически этот вопрос возник, когда функция была «main ()», и контроль наверняка проходил через нулевое деление, и в результате компилятору не разрешалось отклонять даже эту программу. Причина в том, что программа по-прежнему правильно сформирована, и компилятор, отвечающий требованиям, должен принимать все правильно сформированные программы (и отклонять все неправильно сформированные программы и выдавать диагностическое сообщение об ошибке, если не указано иное).

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

Интересно, что утверждение Стандарта о том, что оно «не предъявляет никаких требований», на самом деле очень близко к ошибочности. Это характеристики системы компиляции, поддерживающей отдельную компиляцию, которая не может определить, выполняется ли на самом деле часть кода, для которой нет четко определенного поведения, и поэтому компилятору на самом деле требуется для компиляции в любом случае, потому что это не может сделать вывод, если программа имеет неопределенное поведение.

...