ПрограммированиеC разработчик

Что такое 'undefined behavior' в языке C? Приведите примеры его возникновения и способы минимизации подобных проблем.

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

Ответ.

Undefined Behavior (UB) — это поведение программы, результата которого стандарт языка C не определяет. Компилятор или система могут выполнять любые действия — от незаметной ошибки до полного сбоя или порчи данных.

Типичные причины UB:

  • Доступ за границы массива
  • Разыменование неинициализированного/недействительного указателя
  • Деление на 0
  • Модификация констант

Как минимизировать UB:

  • Всегда инициализировать переменные
  • Проверять индексы массивов
  • Использовать статический и динамический анализатора кода (например, valgrind, AddressSanitizer)

Пример кода:

int arr[5]; arr[10] = 0; // UB — выход за границу массива int* p = NULL; *p = 42; // UB — разыменование NULL-указателя

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

Вопрос: Как поведет себя программа, если выполнять деление целого числа на ноль?

Ответ: По стандарту C (ISO C99 6.5.5), деление на 0 — это undefined behavior. Возможен crash, появление мусора или даже "логически правильный" выход, но стандарт не гарантирует никакого результата.

Пример кода:

int a = 10, b = 0; printf("%d", a / b); // Undefined behavior

История

В одном из проектов на встроенных системах программист написал цикл по массиву, случайно зашёл за его пределы на один элемент. Приложение заработало нормально, но через месяц начала происходить порча других данных в памяти (кратковременные ошибки, сложно воспроизводимые). Проблему нашли только после внимательного ревью и проверки статическим анализатором.


История

Разработчик полагался на то, что результат разыменования NULL-указателя всегда вызывает crash, и поэтому не добавлял проверки на NULL. Однако на редкой платформе это приводило к некорректной (но не фатальной) модификации памяти, что ломало другие структуры и приводило к трудноуловимым багам.


История

При генерации псевдослучайных чисел использовалось деление, и при некоторых значениях входных аргументов возникало деление на 0. На большинстве платформ программа просто "падала", но на одной из них результат был некорректным числом, что привело к невозможности воспроизвести баги между разными средами.