Неопределённое поведение: различия между версиями
[непроверенная версия] | [непроверенная версия] |
Tetromino (обсуждение | вклад) шаблон, оформление, дополнение |
|||
Строка 20: | Строка 20: | ||
== Достоинства == |
== Достоинства == |
||
* Определение некоторых операций как «неопределённых» приводит подобные языки (характеризующиеся зачастую отсутствием встроенной проверки на предел массива и т. д.) к упрощению спецификации |
* Определение некоторых операций как «неопределённых» приводит подобные языки (характеризующиеся зачастую отсутствием встроенной проверки на предел массива и т. д.) к упрощению спецификации и некоторому увеличению гибкости. |
||
* Ускоряется работа программ (так как не нужно проверять всевозможные «маргинальные» случаи). |
* Ускоряется работа программ (так как не нужно проверять всевозможные «маргинальные» случаи). |
||
Версия от 18:57, 5 марта 2010
Неопределённое поведение (англ. undefined behaviour) — свойство некоторых языков программирования (наиболее заметно в C) в определённых маргинальных ситуациях выдавать результат, зависящий от реализации компилятора. Другими словами, спецификация не определяет поведение языка в любых возможных ситуациях, а говорит: «при условии А результат операции Б не определён». Допускать такую ситуацию в программе считается ошибкой; даже если на некотором компиляторе программа успешно выполняется, она не будет кроссплатформенной и может отказать на другой машине, в другой ОС и даже на других настройках компилятора.
Неопределенное поведение не следует путать с неуточняемым поведением (unspecified behavior), при котором спецификация разрешает не любое поведение, а только ограниченный диапазон вариантов реализации.
Примеры
В языке Си, к примеру, использование переменной до её инициализации приводит к неопределённому поведению. Согласно спецификации компилятор должен в этом случае сделать что-либо, что может показаться наиболее эффективным/простым. Неопределённое поведение возникает при попытке обращения к переменной.
Ещё один пример неопределенного поведения: курьёз с ANSI-директивой «#pragma». Согласно спецификации языка компиляторам предоставлена полная свобода при обработке этой конструкции. До версии 1.17 компилятор GCC при нахождении в исходном коде этой директивы пытался запустить Emacs с игрой «Ханойские башни».
В качестве еще одного примера неопределенного поведения можно привести код:
int i = 5;
i = ++i + ++i;
При его выполнении переменная i может принять значения 13 или 14 для C/C++, 13 для Java, PHP и C#, 12 при реализации на LISP. Неопределенность в языке C/C++ связана с тем, что согласно стандартам С и С++ побочные эффекты (т.е. инкремент в данном случае) могут быть применены в любой удобный для компилятора момент между двумя точками следования.
Достоинства
- Определение некоторых операций как «неопределённых» приводит подобные языки (характеризующиеся зачастую отсутствием встроенной проверки на предел массива и т. д.) к упрощению спецификации и некоторому увеличению гибкости.
- Ускоряется работа программ (так как не нужно проверять всевозможные «маргинальные» случаи).
Недостатки
- Не гарантирует полной совместимости различных реализаций языка.
- Недопущение ситуаций неопределённого поведения остаётся за программистом.
Ссылки
Это заготовка статьи о компьютерных языках. Помогите Википедии, дополнив её. |