Pull to refresh

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

Reading time 2 min
Views 12K


Ситуация, когда код на языке C++ синтаксически валиден, однако его поведение не определено в Стандарте, в русскоязычной литературе часто называют просто неопределённым поведением. В самом же Стандарте для таких ситуаций существуют целых 3 термина: undefined behavior, unspecified behavior и implementation-defined behavior. В этой коротенькой заметке мы будем разбираться, чем они отличаются.


Implementation-defined behavior


Этот термин применяется для описания ситуаций, когда C++ код полностью валиден, но его поведение зависит от реализации (например, компилятора или среды исполнения), и это поведение документировано. Например, размер в байтах указателя или типа int зависит от конкретной реализации или настроек компилятора, но это описано в документации, и на эту документацию можно полагаться.


Unspecified behavior


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


Undefined behavior


Это самый опасный вариант неопределённости. В Стандарте он служит для описания поведения, которое может привести к полностью непредсказуемым последствиям. Самые яркие примеры: обращение за границы массива или разыменование указателя на освобождённый объект. Хуже всего то, что программа совершенно не обязательно сразу же завершится или вообще выдаст какую-либо ошибку, тем не менее, на её поведение уже нельзя полагаться.


В заключение ещё раз напомню, что все вышеописанные термины относятся к синтаксически валидному коду, который будет успешно скомпилирован (впрочем, компиляторы зачастую выдают предупреждения для наиболее очевидных случаев undefined behavior). Код, невалидный с точки зрения Стандарта, называется ill-formed program.

Tags:
Hubs:
+11
Comments 30
Comments Comments 30

Articles