TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
C++95

10 Oct 2022, 11:47

Открыть в Telegram Поделиться Пожаловаться

#compiler

clang-format: царь-костыль 🩼

Я раньше писал про clang-tidy в этом блоге. Он нужен для проверки кода на качество. У него модульный вид - каждый может написать свою проверку и использовать множество независимых друг от друга проверок. Он работает на уровне AST, то есть код проходит лексический и синтаксический анализ до тулзы.

А clang-format это еще одна тулза, нужная для форматирования исходного кода - чтобы было нужное количество пробелов, отсортированные #include и прочее. Он работает на уровне токенов, то есть код проходит только лексический анализ до тулзы.

То есть clang-format очень приблизительно понимает, что перед ним за токен и что нужно сделать. Например, текст
class A: B {
ему это видится как последовательность токенов
(kw_class) (identifier) (colon) (identifier) (l_brace)

И clang-format применяет серию захардкоженных правил поверх этих токенов, с поддержкой разной фигни как стека вложенности для скобок. Никакой модульности нет, то есть все правила написаны прямо в глубине тулзы.

Например, в какой-то момент в середине работы вызывается метод WhitespaceManager::generateReplacements, который поправляет пробелы, и в нем внутри метод WhitespaceManager::alignArrayInitializers, чтобы поправить пробелы в массивах.

Совсем без семантики форматировать сложно, поэтому clang-format перед форматированием "аннотирует" токены дополнительными данными: сопоставляет каждому Token структуру FormatToken.
Там есть всякие поля, как bool IsArrayInitializer (то что этот токен - начало array initialization);
или FormatToken *MatchingParen (ссылка на закрывающую скобку).

Работает все при таком подходе очень хреново 😣. Из стандартных ошибок - ставит много где лишние пробелы или портит лямбды.

Есть куча issue про clang-format, а чинить их значительно сложнее чем issue для clang-tidy.
Если в clang-tidy область потенциальных правок - код отдельной проверки (максимум несколько сотен строк), то в clang-format это весь clang-format.

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

И так для многих issue - начинаешь разбираться в мелкой проблеме - почему ставится лишний пробел, раскрываешь всю цепочку причин, и получаешь мега-проблему, которую нереально починить.

Поэтому старайтесь делать модульные программы, чтобы уменьшить область потенциальных правок при починке бага 😎

856 2 5 7 8
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot