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

Поделись знанием:
Перейти к: навигация, поиск

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

Достоинства

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

Недостатки

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

Напишите отзыв о статье "Неопределённое поведение"

Примечания

  1. [books.google.com/books?id=LCCMvmnnicsC Программирование на языке C/C++. Самоучитель]. — Dialektika, 2003-01-01. — 348 с. — ISBN 9785845904607.
  2. Павловская Татьяна Александровна. [books.google.com/books?id=UM1LDAAAQBAJ C/C++. Процедурное и объектно-ориентированное программирование. Учебник для вузов. Стандарт 3-го поколения]. — "Издательский дом ""Питер""", 2014-07-30. — 496 с. — ISBN 9785496001090.
  3. [blog.djmnet.org/2008/08/05/a-pragmatic-decision/ A Pragmatic Decision | D-Mac's Stuff]

Ссылки

  • [www.unix.org.ua/unix2/glava_26.htm Мобильность на уровне исходных текстов]
  • [www.viva64.com/ru/b/0306/ Разыменовывание нулевого указателя приводит к неопределённому поведению]


Отрывок, характеризующий Неопределённое поведение

– Est ce que les dames francaises ne quitteraient pas Paris si les Russes y entraient? [Разве французские дамы не уехали бы из Парижа, если бы русские вошли в него?] – сказал Пьер.
– Ah, ah, ah!.. – Француз весело, сангвинически расхохотался, трепля по плечу Пьера. – Ah! elle est forte celle la, – проговорил он. – Paris? Mais Paris Paris… [Ха, ха, ха!.. А вот сказал штуку. Париж?.. Но Париж… Париж…]
– Paris la capitale du monde… [Париж – столица мира…] – сказал Пьер, доканчивая его речь.
Капитан посмотрел на Пьера. Он имел привычку в середине разговора остановиться и поглядеть пристально смеющимися, ласковыми глазами.
– Eh bien, si vous ne m'aviez pas dit que vous etes Russe, j'aurai parie que vous etes Parisien. Vous avez ce je ne sais, quoi, ce… [Ну, если б вы мне не сказали, что вы русский, я бы побился об заклад, что вы парижанин. В вас что то есть, эта…] – и, сказав этот комплимент, он опять молча посмотрел.
– J'ai ete a Paris, j'y ai passe des annees, [Я был в Париже, я провел там целые годы,] – сказал Пьер.
– Oh ca se voit bien. Paris!.. Un homme qui ne connait pas Paris, est un sauvage. Un Parisien, ca se sent a deux lieux. Paris, s'est Talma, la Duschenois, Potier, la Sorbonne, les boulevards, – и заметив, что заключение слабее предыдущего, он поспешно прибавил: – Il n'y a qu'un Paris au monde. Vous avez ete a Paris et vous etes reste Busse. Eh bien, je ne vous en estime pas moins. [О, это видно. Париж!.. Человек, который не знает Парижа, – дикарь. Парижанина узнаешь за две мили. Париж – это Тальма, Дюшенуа, Потье, Сорбонна, бульвары… Во всем мире один Париж. Вы были в Париже и остались русским. Ну что же, я вас за то не менее уважаю.]
Под влиянием выпитого вина и после дней, проведенных в уединении с своими мрачными мыслями, Пьер испытывал невольное удовольствие в разговоре с этим веселым и добродушным человеком.
– Pour en revenir a vos dames, on les dit bien belles. Quelle fichue idee d'aller s'enterrer dans les steppes, quand l'armee francaise est a Moscou. Quelle chance elles ont manque celles la. Vos moujiks c'est autre chose, mais voua autres gens civilises vous devriez nous connaitre mieux que ca. Nous avons pris Vienne, Berlin, Madrid, Naples, Rome, Varsovie, toutes les capitales du monde… On nous craint, mais on nous aime. Nous sommes bons a connaitre. Et puis l'Empereur! [Но воротимся к вашим дамам: говорят, что они очень красивы. Что за дурацкая мысль поехать зарыться в степи, когда французская армия в Москве! Они пропустили чудесный случай. Ваши мужики, я понимаю, но вы – люди образованные – должны бы были знать нас лучше этого. Мы брали Вену, Берлин, Мадрид, Неаполь, Рим, Варшаву, все столицы мира. Нас боятся, но нас любят. Не вредно знать нас поближе. И потом император…] – начал он, но Пьер перебил его.
– L'Empereur, – повторил Пьер, и лицо его вдруг привяло грустное и сконфуженное выражение. – Est ce que l'Empereur?.. [Император… Что император?..]
– L'Empereur? C'est la generosite, la clemence, la justice, l'ordre, le genie, voila l'Empereur! C'est moi, Ram ball, qui vous le dit. Tel que vous me voyez, j'etais son ennemi il y a encore huit ans. Mon pere a ete comte emigre… Mais il m'a vaincu, cet homme. Il m'a empoigne. Je n'ai pas pu resister au spectacle de grandeur et de gloire dont il couvrait la France. Quand j'ai compris ce qu'il voulait, quand j'ai vu qu'il nous faisait une litiere de lauriers, voyez vous, je me suis dit: voila un souverain, et je me suis donne a lui. Eh voila! Oh, oui, mon cher, c'est le plus grand homme des siecles passes et a venir. [Император? Это великодушие, милосердие, справедливость, порядок, гений – вот что такое император! Это я, Рамбаль, говорю вам. Таким, каким вы меня видите, я был его врагом тому назад восемь лет. Мой отец был граф и эмигрант. Но он победил меня, этот человек. Он завладел мною. Я не мог устоять перед зрелищем величия и славы, которым он покрывал Францию. Когда я понял, чего он хотел, когда я увидал, что он готовит для нас ложе лавров, я сказал себе: вот государь, и я отдался ему. И вот! О да, мой милый, это самый великий человек прошедших и будущих веков.]