Неопределённое поведение: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[непроверенная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
м кирлат
Строка 1: Строка 1:
{{не путать|неуточняемое поведение|неуточняемым поведением}}
{{не путать|неуточняемое поведение|неуточняемым поведением}}
'''Неопределённое поведение''' ({{lang-en|undefined behaviour}}, в ряде источников ''непредсказуемое поведение''<ref>{{Книга|заглавие=Программирование на языке C/C++. Самоучитель|ссылка=https://books.google.com/books?id=LCCMvmnnicsC|издательство=Dialektika|год=2003-01-01|страниц=348|isbn=9785845904607}}</ref><ref>{{Книга|автор=Павловская Татьяна Александровна|заглавие=C/C++. Процедурное и объектно-ориентированное программирование. Учебник для вузов. Стандарт 3-го поколения|ссылка=https://books.google.com/books?id=UM1LDAAAQBAJ|издательство="Издательский дом ""Питер"""|год=2014-07-30|страниц=496|isbn=9785496001090}}</ref>) — свойство некоторых [[язык программирования|языков программирования]] (наиболее заметно в [[Си (язык программирования)|Си]]), [[библиотека подпрограмм|программных библиотек]] и [[аппаратное обеспечение|аппаратного обеспечения]] в определённых маргинальных ситуациях выдавать результат, зависящий от реализации компилятора (библиотеки, микросхемы) и случайных факторов наподобие состояния памяти или сработавшего [[прерывание|прерывания]]. Другими словами, [[спецификация]] не определяет поведение языка (библиотеки, микросхемы) в любых возможных ситуациях, а говорит: «при условии А результат операции Б не определён». Допускать такую ситуацию в программе считается ошибкой; даже если на некотором компиляторе программа успешно выполняется, она не будет [[кроссплатформенность|кроссплатформенной]] и может отказать на другой машине, в другой ОС или при других настройках компилятора.
'''Неопределённое поведение''' ({{lang-en|undefined behaviour}}, в ряде источников ''непредсказуемое поведение''<ref>{{Книга|заглавие=Программирование на языке C/C++. Самоучитель|ссылка=https://books.google.com/books?id=LCCMvmnnicsC|издательство=Dialektika|год=2003-01-01|страниц=348|isbn=9785845904607}}</ref><ref>{{Книга|автор=Павловская Татьяна Александровна|заглавие=C/C++. Процедурное и объектно-ориентированное программирование. Учебник для вузов. Стандарт 3-го поколения|ссылка=https://books.google.com/books?id=UM1LDAAAQBAJ|издательство="Издательский дом ""Питер"""|год=2014-07-30|страниц=496|isbn=9785496001090}}</ref>) — ситуация, когда в определённых маргинальных ситуациях поведение программного продукта или устройства может меняться неконтролируемым образом и приводить к некорректным результатам, но это не является ошибкой, и о такой возможности указано в спецификации. Чаще всего речь идёт о неопределённом поведении в языках программирования.


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

Версия от 12:52, 10 сентября 2023

Неопределённое поведение (англ. undefined behaviour, в ряде источников непредсказуемое поведение[1][2]) — ситуация, когда в определённых маргинальных ситуациях поведение программного продукта или устройства может меняться неконтролируемым образом и приводить к некорректным результатам, но это не является ошибкой, и о такой возможности указано в спецификации. Чаще всего речь идёт о неопределённом поведении в языках программирования.

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

Примеры

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

Библиотеки могут не проверять указатели на NULL для быстродействия.

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

Ещё один пример неопределенного поведения: курьёз с ANSI-директивой «#pragma». Согласно спецификации языка, компиляторам предоставлена полная свобода при обработке этой конструкции. До версии 1.17 компилятор GCC при нахождении в исходном коде этой директивы пытался запустить Emacs с игрой «Ханойские башни».[3]

В качестве ещё одного примера неопределённого поведения можно привести код:

int i = 5;
i = ++i + ++i;

При его выполнении переменная i может принять значения 13 или 14 для C/C++, 13 для Java, PHP и C#, 12 при реализации на LISP. Неопределенность в языках C и C++ связана с тем, что, согласно стандартам C и C++, побочные эффекты (то есть инкремент в данном случае) могут быть применены в любой удобный для компилятора момент между двумя точками следования.

Достоинства

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

Недостатки

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

Примечания

  1. Программирование на языке C/C++. Самоучитель. — Dialektika, 2003-01-01. — 348 с. — ISBN 9785845904607.
  2. Павловская Татьяна Александровна. C/C++. Процедурное и объектно-ориентированное программирование. Учебник для вузов. Стандарт 3-го поколения. — "Издательский дом ""Питер""", 2014-07-30. — 496 с. — ISBN 9785496001090.
  3. A Pragmatic Decision | D-Mac's Stuff. Дата обращения: 21 марта 2009. Архивировано 1 июня 2009 года.

Ссылки