Открыть сервис

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. Процесс анализа включает несколько этапов:

  1. Парсинг исходного кода — Clang-Tidy использует тот же препроцессор и синтаксический анализатор, что и компилятор Clang, что обеспечивает полную совместимость с языковыми конструкциями и директивами препроцессора.
  2. Построение AST — после парсинга строится абстрактное синтаксическое дерево, представляющее структуру программы.
  3. Запуск чекеров — каждый активный чекер (проверка) обходит AST и ищет заданные паттерны, нарушения или потенциальные проблемы.
  4. Генерация отчёта — найденные проблемы выводятся в стандартный поток ошибок (stderr) или в файл в формате JSON, если указан соответствующий флаг.
  5. Применение исправлений — для диагностик с поддержкой 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 →