Какие языки имеют «задокументированное неопределенное поведение»? - PullRequest
0 голосов
/ 23 октября 2019

Подробное объяснение для тега начинается очень разумно:

В компьютерном программировании относится неопределенное поведение (неофициально "UB")к компьютерному коду, поведение которого не определено стандартом языка программирования при определенных условиях.

, но затем говорит (выделение мое):

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

Как "заданное" поведение "может быть" задокументировано "?

Что такое «задокументированное неопределенное поведение» и на каких языках этот зверь ?

[Дополнительный комментарий:

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

(Примечание. Я уже несколько раз поднимал вопрос о том, что это за текст, как в вопросе, так и в ответе, но каждый раз, когда мои комментарии удалялись очень резко.)]

РЕДАКТИРОВАТЬ

отредактируйте, чтобы подробно объяснить уникальные части вашего вопроса

Опять-таки уникальные части:

  • Как можно "неопределенное поведение"быть одновременно" документированным "?
  • Что такое" документированное неопределенное поведение "?
  • Какие языки имеют" документированное неопределенное поведение "?

Ни один изсвязанный вопрос отвечает на эти вопросы;слова задокументированное неопределенное поведение даже не появляются вместе .

Если я что-то пропустил, было бы полезно указать конкретно на ответы, которые объясняютэти .

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

Ответы [ 3 ]

2 голосов
/ 24 октября 2019

Я был тем, кто написал этот текст в вики. То, что я имел в виду под «документированным неопределенным поведением», является формально неопределенным поведением в стандарте языка, но совершенно четко определенным в реальном мире. Ни один язык не имеет «задокументированного неопределенного поведения», но реальный мир не всегда заботится о том, что говорит языковой стандарт.

Возможно, лучшим термином будет нестандартные языковые расширения , илиесли вы будете «неопределенными в том, что касается стандарта языка программирования».

Есть несколько причин, по которым что-то можно рассматривать как неопределенное поведение в стандарте языка:

  1. Что-топросто выходит за рамки стандарта. Такие как поведение памяти, мониторов и т. Д. Все поведение, которое не задокументировано в стандарте, теоретически не определено.
  2. Что-то на самом деле хорошо определено на данном конкретном оборудовании, но стандарт не хочетналожить ограничения на систему / оборудование, чтобы ни одна технология не получила несправедливого рыночного преимущества. Поэтому он маркирует что-то неопределенное поведение, даже если это не практикуется.
  3. Что-то действительно неопределенное поведение даже в оборудовании или не имеет никакого смысла ни в каком контексте.

Пример 1)
Где хранятся переменные в памяти? Это выходит за рамки стандарта, но совершенно четко определено на любом компьютере, на котором выполняются программы.

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

Пример 2)
Переполнение целого числа со знаком. Что происходит в случае целочисленного переполнения, совершенно четко определено на уровне процессора. В большинстве случаев само значение будет рассматриваться как простое беззнаковое сложение / вычитание, но в регистре состояния будет установлен флаг переполнения. Что касается языка C или C ++, такие переполнения в теории могут вызвать ужасные, необъяснимые события. Но в действительности базовое аппаратное обеспечение будет давать совершенно четкие результаты.

Пример 3)
Деление на ноль. Доступ к неверным адресам. Поведение при переполнении стека. И т.д.

1 голос
/ 23 октября 2019

C и C ++ довольно уникальны в том смысле, что «официальные» стандарты C были написаны задолго до того, как язык уже использовался, и даже были описаны в опубликованных книгах. Было много ситуаций, таких как целочисленное переполнение, которые некоторые реализации обрабатывали бы документированным предсказуемым образом, но другие не могли делать это дешево. Стандарт рассматривает такие вещи, как «неопределенное поведение», явно отмечая, что реализация может (но не обязательна) обрабатывать их в документированной характеристике среды. Обратите внимание, что это допускает возможность того, что в некоторых средах может быть дорого гарантировать какое-либо согласованное поведение, и что многие программы могут не предлагать такие гарантии, несмотря на стоимость.

Рассмотрим, например, что-то вроде:

extern volatile int someFlag;
void test(int x, int y)
{
  int z;
  someFlag = 1;
  z=x+y;
  someFlag = 0;
  if (f2())
    f3(x,y,z);        
}

Если в реализации, когда переполнение вызывает сигнал, разрешено изменить код на:

extern volatile sig_atomic_t someFlag;
void test(int x, int y)
{
  someFlag = 1;
  someFlag = 0;
  if (f2())
    f3(x,y,x+y);
}

Это позволит избежать необходимости сохранять значение x+y впамять через вызов f2(), и может избежать необходимости вычислять его полностью. Чистый выигрыш , если только someFlag не повлияет на поведение сигнала переполнения целых чисел так, как полагается код. Если бы стандарт характеризовал целочисленное переполнение как «Определено реализацией», было бы неудобно для реализаций документировать поведение переполнения в соответствии с требованиями Стандарта, не отказываясь от оптимизаций, подобных описанным выше, даже если для многих целей гарантируется, что добавление будет выполнено довызов f2 добавил бы стоимость, но не какое-либо значение.

Вместо того, чтобы беспокоиться о том, следует ли разрешать или запрещать такую ​​оптимизацию, авторы Стандарта решили охарактеризовать целочисленное переполнение как неопределенное поведение, позволяяреализации, которые документировали его поведение, чтобы продолжать делать это, но не требуют, чтобы реализации пессимистически предполагали, что любые возможные побочные эффекты могут быть наблюдаемы способами, о которых они не знают. До того, как был написан Стандарт, любое поведение, которое документировала реализация, было бы документированным поведением, и тот факт, что Стандарт характеризовал поведение как Неопределенное, не предназначался для его изменения.

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

0 голосов
/ 23 октября 2019

Насколько я понимаю, «документированное неопределенное поведение» не означает «поведение, которое является одновременно (неопределенным И документированным)». Это означает «(неопределенное поведение), которое задокументировано». Он даже приводит пример:

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

Неопределенное поведение - это доступ к последнему элементу массива вC». Язык C говорит: ЭТО НЕ ОПРЕДЕЛЕНО. И все же, он и другие документировали, что на самом деле происходит в реальном слове, когда вы входите в эту «неопределенную» область языка.

Итак, есть два уровня, на которых задокументировано это неопределенное поведение.

1) Оно идентифицировано. Msgstr "C не определяет, что происходит, когда вы идете за конец массива". Теперь вы знаете, что это неопределенное поведение.

2) Это изучено. «Вот некоторые вещи, которые могут произойти, когда вы это делаете».

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...