Главная
Новости
Статьи
Ремонт
Каркасный дом
Несущие конструкции
Металлические конструкции
Прочность дорог
Дорожные материалы
Стальные конструкции
Грунтовые основания
Опорные сооружения




06.05.2021


05.05.2021


05.05.2021


04.05.2021


03.05.2021


02.05.2021


30.04.2021





Яндекс.Метрика

Неопределённое поведение

05.03.2021

Неопределённое поведение (англ. undefined behaviour, в ряде источников непредсказуемое поведение) — свойство некоторых языков программирования (наиболее заметно в Си), программных библиотек и аппаратного обеспечения в определённых маргинальных ситуациях выдавать результат, зависящий от реализации компилятора (библиотеки, микросхемы) и случайных факторов наподобие состояния памяти или сработавшего прерывания. Другими словами, спецификация не определяет поведение языка (библиотеки, микросхемы) в любых возможных ситуациях, а говорит: «при условии А результат операции Б не определён». Допускать такую ситуацию в программе считается ошибкой; даже если на некотором компиляторе программа успешно выполняется, она не будет кроссплатформенной и может отказать на другой машине, в другой ОС или при других настройках компилятора.

Неопределенное поведение не следует путать с неуточняемым поведением (unspecified behavior), при котором спецификация разрешает не любое поведение, а только ограниченный диапазон вариантов реализации.

Примеры

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

Большинство[сколько?] библиотек не проверяют указатели на NULL.

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

Ещё один пример неопределенного поведения: курьёз с 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++ связана с тем, что согласно стандартам С и С++ побочные эффекты (то есть инкремент в данном случае) могут быть применены в любой удобный для компилятора момент между двумя точками следования.

Достоинства

  • Определение некоторых операций как «неопределённых» приводит подобные языки (характеризующиеся зачастую отсутствием встроенной проверки на предел массива и т. д.) к упрощению спецификации и некоторому увеличению гибкости.
  • Ускоряется работа программ (так как не нужно проверять всевозможные «маргинальные» случаи).

Недостатки

  • Не гарантирует полной совместимости различных реализаций языка.
  • Недопущение ситуаций неопределённого поведения остаётся за программистом.