ПрограммированиеСистемный разработчик, Backend разработчик

Что такое undefined behavior (неопределённое поведение) в C++ и почему оно так опасно? Приведите примеры и объясните, как его избегать.

Проходите собеседования с ИИ помощником Hintsage

Ответ.

Undefined behavior (UB, неопределённое поведение) — это действия в коде, поведение которых стандарт не определяет. В таких случаях компилятор волен принимать любые решения: программа может работать по-разному на разных платформах, компиляторах, или даже запустить ядерную войну (формально!). Использование UB — самая опасная ошибка в C++.

Примеры UB:

  • Доступ за пределы массива
  • Использование неинициализированных переменных
  • Освобождение одной области памяти дважды
  • Использование dangling pointers (висячих указателей)
int* p = new int[2]; delete[] p; int x = p[1]; // UB: доступ к памяти после освобождения

Для предотвращения UB:

  • Всегда инициализируйте переменные;
  • Проверяйте границы массивов/контейнеров;
  • Избегайте ручного управления памятью, используйте smart pointers.

Вопрос с подвохом.

Что произойдет при следующем коде?

int a = 42; int b = a++ + ++a;

Какое значение будет у b?

Ответ:

Данный код вызывает UB, потому что изменяет и читает переменную a без последовательности точек последовательности (sequence points) между операциями. Стандарт не гарантирует определенного результата, и компилятор может получить любой результат или даже сгенерировать неожиданный код.

Примеры реальных ошибок из-за незнания тонкостей темы.


История На проекте системы хранения данных один из разработчиков допустил выход за пределы массива в низкоуровневой функции. UB проявлялось только на определённых пользовательских данных и приводило к разрушению структуры файла и потере данных клиентов.


История В проекте для микроконтроллеров встречались конструкции с чтением неинициализированных переменных. Тесты проходили, но спустя год после выхода устройства выявились случайные ошибки в эксплуатации, вызванные UB: переменные иногда содержали мусорные значения.


История В большом open-source проекте был обнаружен дескриптор, освобождаемый дважды из разных частей кода. Это UB сначала проявлялось крайне редко, но в новых версиях ОС стало приводить к частым аварийным остановкам.