Хабрахабр

Статический анализ улучшит кодовую базу сложных C++ проектов

Старые большие проекты

Постепенно и незаметно складывается ситуация, когда сложность серьёзных C++ проектов становится запредельной. К сожалению, теперь C++ программист не может полагаться только на свои силы.
Во-первых, кода стало так много, что уже невозможна ситуация, когда в проекте есть хотя бы парочка программистов, которые знают проект целиком. Например, ядро Linux 1.0.0 содержало около 176 тысяч строк кода. Это много, но была возможность поставить рядом кофе-машину и за пару недель более или менее просмотреть весь код и понять общие принципы его работы. Если же брать ядро Linux 5.0.0, то размер кодовой базы составляет уже около 26 миллионов строк кода. Код ядра вырос почти в 150 раз. Можно только выбрать несколько частей проекта и принимать участие в их развитии. Невозможно сесть и разобраться, как именно это всё работает, какие есть взаимосвязи между различными участками кода.

С одной стороны, это хорошо, так как появляются конструкции, которые позволяют писать более компактный и безопасный код. Во-вторых, язык C++ продолжает быстро развиваться. В них переплетаются старые и новые подходы к написанию кода. С другой стороны, в силу обратной совместимости, старые большие проекты становятся разнородными. Из-за этого с каждым годом погружаться в проекты, написанные на C++, становится всё сложнее и сложнее. Напрашивается аналогия с кольцами на срезе дерева. Чтобы всесторонне изучить С++ требуется слишком много времени. Нужно одновременно разбираться в коде, как написанном ещё в стиле C с классами, так и в современных подходах (лямбдах, семантике перемещения и т.д.). Это приводит к дополнительным дефектам, но нерационально из-за этого остановиться и ждать, когда все разработчики станут идеально знать C++. Но поскольку развивать проекты все равно требуется, люди начинают писать код на C++, так и не изучив до конца всех его нюансов.

Нет. Ситуация безнадёжна? Многие бывалые программисты в этот момент скривили губы, как будто им подсунули лимон :). На помощь приходит новый класс инструментов: статические анализаторы кода. Мы линтеры ещё 20 лет назад запускали. Мол, знаем мы эти ваши линтеры… Сообщений много, толку мало… Да и какой же это новый класс инструментов?!

То, что было 10-20 лет назад, это совсем не те инструменты, которые сейчас называются статическими анализаторами. И всё-таки я рискну утверждать, что это именно новый класс инструментов. Они тоже относятся к инструментам статического анализа, но сейчас мы говорим о выявлении ошибок в коде. Во-первых, я не говорю об инструментах, ориентированных на форматирование кода. Это совсем не те линтеры 20-ти летней давности, построенные на регулярных выражениях. Во-вторых, современные инструменты используют сложные технологии анализа, учитывая взаимосвязи между разными функциями и фактически виртуально выполняя некоторые участки кода. Чтобы находить ошибки, используются такие технологии, как анализ потока данных, автоматическое аннотирование методов, символьное выполнение и так далее. Кстати, нормальный статический анализатор вообще нельзя сделать на регулярных выражениях.

Загляните в эту статью, чтобы посмотреть благодаря чему анализаторы могут находить интереснейшие ошибки. Это всё не абстрактные слова, а реальность, которую я наблюдаю, являясь одним из создателей инструмента PVS-Studio.

Причем анализаторы знают больше, чем даже профессиональные разработчики. Однако намного важнее, что современные статические анализаторы обладают обширными знаниями по паттернам ошибок. Например, если специально про это где-то не прочитать, то вы никогда не догадаетесь, что вызовы функции memset для затирания приватных данных иногда исчезают, так как с точки зрения компилятора вызов функции memset избыточен. Слишком сложно стало учитывать и помнить все нюансы при написании кода. Или кто, например, знает, что опасного в подобном наполнении контейнера? А между тем, это серьезный дефект безопасности CWE-14, который обнаруживается буквально везде.

std::vector<std::unique_ptr<MyType>> v;
v.emplace_back(new MyType(123));

Думаю, далеко не все и не сразу сообразят, что подобный код потенциально опасен и может приводить к утечкам памяти.

Например, в отличие от человека, им не лень заглянуть в заголовочные файлы, чтобы убедиться, что isspace и sprintf — это настоящие функции, а не безумные макросы, которые всё портят. Помимо обширного знания паттернов статические анализаторы бесконечно внимательны и никогда не устают. Подобные случаи демонстрируют суть сложности поиска ошибок в больших проектах: меняется что-то в одном месте, а ломается в другом.

Это уже постепенно происходит и на конференциях, посвященных процессу разработки, где всё чаще упоминается статический анализ как одна из первых линий обороны для борьбы с багами. Я убеждён, что в скором времени статический анализ станет неотъемлемой частью DevOps — это будет столь же естественно и необходимо, как использование системы контроля версий.

Неэффективно искать глупые ошибки и опечатки, используя юнит-тесты или ручное тестирование. Статический анализ выполняет своего рода роль фильтра грубой очистки. Эта мысль, а также важность регулярного применения анализатора, хорошо описана в статье "Внедряйте статический анализ в процесс, а не ищите с его помощью баги". Намного быстрее и дешевле исправить их сразу после написания кода, используя для обнаружения проблем статический анализ.

Да, это так. Кто-то может сказать, что нет смысла в специальных инструментах, так как подобные статические проверки учатся делать и компилятор. Например, каждый раз проверяя LLVM мы находим там ошибки с помощью PVS-Studio. Однако, статические анализаторы естественно тоже не стоят на месте и как специализированные инструменты превосходят компиляторы.

Как говорится, выбирайте на свой вкус. Мир предлагает большое количество инструментов статического анализа кода. Используйте статические анализаторы кода и улучшите качество вашей кодовой базы! Хотите находить множество ошибок и потенциальных уязвимостей ещё на этапе написания кода?

Why Static Analysis Can Improve a Complex C++ Codebase Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать эту ссылку: Andrey Karpov.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть