Введение
Каждый разработчик знает: ошибки бывают разными — от опечаток до логических просчетов. Но есть одна категория багов, которая кажется невозможной. Ошибка, которую никто никогда не совершал. Ведь так, да? Однако именно такой случай недавно описали инженеры из PVS-Studio в своей статье на Habr. Они разобрали ситуацию, когда программист случайно нарушил правило, которое, казалось бы, знает каждый новичок. Эта история — не просто курьез, а серьезный повод задуматься о том, как мы тестируем код и какие «очевидные» истины могут оказаться ловушками.
Речь идет о баге в коде, который был найден статическим анализатором. Авторы статьи Источник подчеркивают: ошибка настолько тривиальна, что ее редко кто допускает осознанно. Но именно это делает ее особенно опасной — разработчик просто не ожидает, что такое может произойти.
Что за ошибка и почему она уникальна?
В статье PVS-Studio описывается баг, связанный с неправильным использованием оператора sizeof в языке C/C++. Если вы пишете на C, вы знаете: sizeof — это оператор, который возвращает размер типа или переменной в байтах. И, казалось бы, его легко использовать правильно. Но авторы нашли пример, где программист написал:
int *ptr = (int*)malloc(sizeof(ptr));
На первый взгляд — обычный код. Но проблема в том, что sizeof(ptr) возвращает размер указателя, а не размер массива, на который он указывает. В 64-битной системе указатель занимает 8 байт, в то время как int — обычно 4 байта. Если разработчик хотел выделить память для 100 целых чисел, он должен был написать sizeof(int) * 100 или sizeof(*ptr) * 100. Ошибка, которую никто никогда не совершал — ведь это же очевидно, правда? Но в реальном проекте такой баг прошел код-ревью и попал в продакшен.
Почему это стало возможным?
Авторы статьи объясняют: подобные ошибки возникают из-за усталости или поспешности. Программист мог скопировать строку из другого места, не подумав. Но главная причина — человеческий фактор. Даже опытные разработчики иногда совершают «детские» ошибки, когда работают под давлением сроков. В материале PVS-Studio приводится статистика: по данным их анализатора, около 15% всех найденных багов относятся к категории «очевидных», но их никто не замечает без автоматической проверки.
Это не единичный случай. В блоге компании регулярно публикуются разборы похожих ляпов — например, когда разработчики путают strlen и sizeof при работе со строками. Но именно этот пример стал вирусным из-за своей парадоксальности: «Ошибка, которую никто никогда не совершал» — ироничный заголовок, который привлекает внимание.
Как избежать таких багов на практике?
Команда PVS-Studio рекомендует три простых шага:
-
Используйте статические анализаторы кода. Даже бесплатные инструменты, такие как Clang Static Analyzer или Cppcheck, могут отловить подобные ляпы. В статье подчеркивается, что анализатор PVS-Studio нашел этот баг именно благодаря правилу V507 — проверка на несоответствие размера указателя и типа данных.
-
Пишите юнит-тесты. Если бы разработчик написал тест, который проверяет, что выделяется память ровно под 100 элементов, ошибка выявилась бы на этапе компиляции или тестирования.
-
Делайте код-ревью с чек-листами. Вместо того чтобы просто просматривать код, используйте список типичных ошибок. Например: «Проверить, что sizeof применяется к типу, а не к указателю». Это снижает риск пропустить «очевидную» проблему.
Реальный кейс: как такой баг влияет на бизнес?
Представьте, что этот код используется в embedded-системе для управления двигателем. Выделение памяти на 8 байт вместо 400 байт приведет к переполнению буфера. В лучшем случае — падение программы, в худшем — аварийная остановка оборудования. Ошибка, которую никто никогда не совершал, может стоить миллионы долларов.
Авторы статьи упоминают, что подобные баги часто встречаются в проектах, где используется наследие C/C++ — например, в финансовых системах или медицинском ПО. Команда проекта применила статический анализ и обнаружила более 50 таких же ляпов в одном проекте.
Итоги
Главный вывод из этой истории: не верьте в «очевидность». Ошибка, которую никто никогда не совершал, — это миф. Каждый разработчик может допустить глупый ляп, особенно под давлением. Статья PVS-Studio — отличное напоминание о том, что автоматизация проверок кода — не роскошь, а необходимость. Если вы пишете на C/C++, обязательно настройте статический анализ уже сегодня. И помните: даже самый опытный программист иногда забывает, что sizeof(ptr) — это не то же самое, что sizeof(int).
В мире разработки нет «невозможных» ошибок. Есть только те, которые мы еще не нашли.
Комментарии