Руководство по стилю кода

Инструмент форматирования

Проект использует clang-format, чтобы стиль кода был единым. Файл .clang-format в корне проекта основан на руководстве Google C++ Style Guide с несколькими поправками, специфичными для проекта.

Установка clang-format

Перед использованием убедитесь, что clang-format доступен:

  • Windows:

    winget install LLVM
    # or with Chocolatey
    choco install llvm
  • Linux:

    sudo apt install clang-format              # Ubuntu/Debian
    sudo dnf install clang-tools-extra         # Fedora
  • macOS:

    brew install clang-format

Использование

  1. Форматирование одного файла:

    clang-format -i path/to/your/file.cpp
  2. Форматирование всего проекта:

    # Run from the project root
    find main -iname '*.h' -o -iname '*.cc' | xargs clang-format -i
  3. Проверка форматирования без изменения файлов (удобно в CI / pre-commit):

    clang-format --dry-run -Werror path/to/your/file.cpp

Интеграция с IDE

  • Visual Studio Code:

    1. Установите расширение C/C++.
    2. В настройках задайте C_Cpp.formatting равным clangFormat.
    3. При желании включите editor.formatOnSave.
  • CLion:

    1. Откройте в настройках Editor > Code Style > C/C++.
    2. Задайте Formatter равным clang-format.
    3. Выберите «use the .clang-format file in the project».

Основные правила

  • Отступ — 4 пробела.
  • Ширина строки — не более 100 символов.
  • Фигурные скобки в стиле attach ({ на той же строке, что и управляющая конструкция).
  • Указатели и ссылки привязываются к типу (выравнивание влево).
  • Директивы include сортируются автоматически.
  • Спецификаторы доступа сдвигаются на -4 пробела.

Среда выполнения C++ и обработка ошибок

  • Код проекта на C++ рассчитан на GNU C++23. Не требуйте в main/ более новых возможностей языка.
  • Исключения C++ и RTTI отключены. Не используйте throw, try/catch, dynamic_cast и typeid.
  • Для владеемых ресурсов используйте RAII — в том числе для дескрипторов ESP-IDF и API на C с явными функциями освобождения. Сырые указатели не владеют ресурсом, если интерфейс не оговаривает иное.
  • Для восстановимых ошибок, которым нужно значение ошибки, возвращайте std::expected<T, E>. В горячих путях предпочитайте небольшой enum или esp_err_t, а преобразовывать ошибки в строки следует на границах протокола или интерфейса.
  • Перед разыменованием проверяйте expected. Не вызывайте value() для непроверенного результата: при отключённых исключениях неверный доступ завершает работу прошивки.
  • Нарушение инвариантов, за которые отвечает программист, считайте фатальным: используйте assert или явный abort, а не моделируйте их как восстановимые ошибки времени выполнения.
  • В путях аудио реального времени используйте ограниченные очереди и избегайте повторных выделений памяти. Если максимум известен, применяйте хранилище фиксированной ёмкости; пул добавляйте только после того, как профилирование покажет частые выделения и освобождения или фрагментацию.

Примечания

  1. Перед коммитом убедитесь, что код отформатирован.
  2. Не правьте выравнивание вручную после запуска clang-format.
  3. Чтобы исключить блок из форматирования, оберните его так:
    // clang-format off
    your code
    // clang-format on
    

Частые вопросы

  1. Форматирование завершается ошибкой:

    • Проверьте, не слишком ли стар clang-format.
    • Убедитесь, что файл в кодировке UTF-8.
    • Проверьте синтаксис файла .clang-format.
  2. Результат отличается от ожидаемого:

    • Проверьте, что .clang-format из корня проекта действительно подхватывается.
    • Убедитесь, что не побеждает другой .clang-format, лежащий выше по дереву.

Вопросы и предложения приветствуются — откройте issue или pull request.

Источник: docs/code_style.md в 78/xiaozhi-esp32