Clang-Tidy
Clang-Tidy — это статический анализатор кода на языках C, C++ и Objective-C, входящий в состав набора инструментов Clang. Он предназначен для автоматического выявления потенциальных ошибок, нарушений стиля кодирования, избыточных конструкций и несоответствий современным стандартам языков. Clang-Tidy поддерживает механизм автоматического исправления (fix-its) для многих диагностик, что позволяет не только находить, но и исправлять проблемы в коде.
История
Разработка Clang-Tidy началась как часть проекта LLVM/Clang. Первый публичный релиз состоялся в 2012 году в составе LLVM 3.3. Изначально инструмент создавался как экспериментальная утилита для проверки кода на соответствие правилам проекта LLVM, но быстро получил распространение за его пределами. Ключевым вкладом в развитие стала интеграция с системой сборки CMake через флаг CMAKE_CXX_CLANG_TIDY, что позволило запускать проверки непосредственно в процессе сборки.
В 2015 году, с выходом LLVM 3.7, Clang-Tidy получил поддержку пользовательских чекеров (проверок) на основе LibTooling — библиотеки для анализа кода Clang. Это позволило разработчикам создавать собственные правила проверки без модификации исходного кода Clang-Tidy. С 2018 года (LLVM 7.0) инструмент активно используется в крупных проектах, включая ядро Linux, Chromium, LLVM, Qt и другие.
Архитектура и принцип работы
Clang-Tidy работает на основе LibTooling — библиотеки, предоставляющей интерфейс для анализа синтаксического дерева (AST) исходного кода, построенного компилятором Clang. Процесс анализа включает несколько этапов:
- Парсинг исходного кода — Clang-Tidy использует тот же препроцессор и синтаксический анализатор, что и компилятор Clang, что обеспечивает полную совместимость с языковыми конструкциями и директивами препроцессора.
- Построение AST — после парсинга строится абстрактное синтаксическое дерево, представляющее структуру программы.
- Запуск чекеров — каждый активный чекер (проверка) обходит AST и ищет заданные паттерны, нарушения или потенциальные проблемы.
- Генерация отчёта — найденные проблемы выводятся в стандартный поток ошибок (stderr) или в файл в формате JSON, если указан соответствующий флаг.
- Применение исправлений — для диагностик с поддержкой fix-its Clang-Tidy может автоматически вносить изменения в исходный код.
Чекеры
Clang-Tidy включает более 400 встроенных чекеров, разделённых на категории. Категории обозначаются префиксами, например:
clang-analyzer-*— проверки, основанные на анализе потока данных (утечки памяти, разыменование нулевых указателей, деление на ноль);bugprone-*— выявление распространённых ошибок, таких как неинициализированные переменные, неправильное использованиеsizeof, путаница между++iиi++в циклах;modernize-*— рекомендации по замене устаревших конструкций на современные (например, заменаNULLнаnullptr, использованиеauto, замена циклов на алгоритмы STL);performance-*— оптимизации производительности, такие как передача больших объектов по константной ссылке вместо копирования, использованиеemplace_backвместоpush_back;readability-*— улучшение читаемости кода: удаление избыточных скобок, замена макросов на константы, избегание длинных строк;cppcoreguidelines-*— проверки на соответствие рекомендациям C++ Core Guidelines;llvm-*— правила оформления кода, принятые в проекте LLVM;google-*— правила из руководств по стилю Google (Google C++ Style Guide);cert-*— проверки, соответствующие стандартам CERT по безопасному программированию.
Применение
Clang-Tidy используется в различных сценариях разработки:
- Непрерывная интеграция (CI) — инструмент запускается автоматически при каждом коммите или pull request. В случае обнаружения критических ошибок сборка может быть остановлена.
- Локальный анализ перед коммитом — разработчики запускают Clang-Tidy вручную или через хуки Git (pre-commit hooks) для проверки изменений.
- Рефакторинг кода — с помощью fix-its Clang-Tidy может автоматически заменять устаревшие конструкции, например, заменять
throw()наnoexceptили добавлятьoverrideк виртуальным функциям. - Обучение и аудит кода — инструмент помогает выявлять систематические ошибки в кодовой базе, особенно в проектах с большим количеством участников.
Интеграция с системами сборки
Clang-Tidy поддерживает несколько способов интеграции:
- CMake — с помощью переменной
CMAKE_CXX_CLANG_TIDYможно указать путь к Clang-Tidy и набор чекеров. Анализатор запускается для каждого компилируемого файла. - compile_commands.json — файл, генерируемый CMake (или другими системами сборки), содержит команды компиляции для каждого файла. Clang-Tidy может использовать этот файл для анализа, не требуя повторной сборки.
- Прямой запуск —
clang-tidy file.cppанализирует указанный файл, используя флаги компиляции, переданные через--или-p.
Настройка
Clang-Tidy настраивается через файл .clang-tidy в корне проекта или через аргументы командной строки. Файл .clang-tidy имеет формат YAML и позволяет:
- Включать или отключать конкретные чекеры (например,
Checks: '-,bugprone-,modernize-*'); - Задавать значения для параметров чекеров (например, порог длины строки для
readability-line-length); - Определять исключения для определённых файлов или каталогов;
- Настраивать формат вывода.
Пример .clang-tidy:
```yaml Checks: '-,clang-analyzer-,bugprone-,modernize-' WarningsAsErrors: 'clang-analyzer-*' CheckOptions:
- key: readability-line-length.LineLength
value: 120 ```
Ограничения
- Ложные срабатывания — некоторые чекеры могут выдавать предупреждения на корректный код, особенно в сложных шаблонных конструкциях или при использовании макросов.
- Зависимость от флагов компиляции — для корректного анализа Clang-Tidy должен знать все флаги компиляции, используемые при сборке. Если флаги не указаны, анализ может быть неполным или некорректным.
- Скорость работы — анализ больших проектов может занимать значительное время, особенно при включении всех чекеров. Для ускорения рекомендуется запускать только необходимые проверки.
- Не заменяет динамический анализ — Clang-Tidy не выявляет ошибки времени выполнения, такие как гонки данных или переполнение буфера, которые требуют динамического анализа (например, AddressSanitizer, ThreadSanitizer).
Сравнение с аналогами
Clang-Tidy является одним из наиболее популярных статических анализаторов для C/C++ наряду с:
- Cppcheck — более лёгкий анализатор, ориентированный на выявление ошибок, но с меньшим набором чекеров и без поддержки fix-its.
- PVS-Studio — коммерческий анализатор с широкими возможностями, но платной лицензией.
- Clang Static Analyzer — встроенный в Clang анализатор, фокусирующийся на глубоком анализе потока данных, но не поддерживающий стилистические проверки.
- SonarQube — платформа для анализа кода, которая может использовать Clang-Tidy как один из инструментов.
Примеры использования
Проверка одного файла
``bash clang-tidy main.cpp -- -std=c++17 -I./include ``
Запуск с автоматическим исправлением
``bash clang-tidy --fix main.cpp -- -std=c++17 ``
Использование в CMake
``cmake set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=-,bugprone-,modernize-*") ``
Источники
- Документация LLVM: «Clang-Tidy — Extra Clang Tools»
- Официальный репозиторий LLVM на GitHub
- Книга «Professional CMake: A Practical Guide» (Craig Scott)
- Стандарт C++ Core Guidelines (C++ Alliance)
- Руководство по стилю Google C++
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →