TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.36K subscribers
Post #868 4.34K
include what you use
#опытным

Еще один способ уменьшить время сборки.

Ваша программа может содержать все хэдэры стандартной библиотеки и прекрасно собираться. В чем проблема? Неиспользуемые шаблоны же не компилируются.

Не компилируются, но анализируются. Если включить в вашу единицу трансляции кучу ненужных хэдэров, то вся эта куча ненужного кода все равно будет как минимум анализироваться на этапе компиляции на соответствие синтаксису. И на это тратится время. А инклюдятся не только шаблоны, поэтому как максимум в объектный файл могут попасть совершенно неиспользуемые части.

Чтобы избежать лишнего анализа, есть такая практика в программировании на С/С++ - include what you use. Включайте в код только те заголовочники, где определены сущности, которые вы используете в коде. Тогда не будет тратится время на анализ ненужного кода.

У этого подхода есть еще одно преимущество. Если мы полагаемся на неявное включение одних хэдэров через другие, то могут возникнуть проблемы при рефакторинге. Вы вроде был убрали только ненужный функционал вместе с объявлениями соответствующих сущностей, а билд сломался с непонятной ошибкой. Потому что вы убрали источник тех неявно подключаемых заголовков и компилятору теперь их недостает. А мы знаем, какие он "шедевры" может выдавать, если ему чего-то не хватает(тот же пример с std::ranges::less)

Как использовать этот подход в проекте?

Я знаю пару способов:

1️⃣ Утилита iwyu. Установив ее и прописав зависимости в симейке, на этапе компиляции вам будут выдаваться варнинги, которые нужно будет постепенно фиксить:

# установка

sudo apt-get install iwyu

# интеграция с cmake

option(ENABLE_IWYU "Enable Include What You Use" OFF)

if(ENABLE_IWYU)
find_program(IWYU_PATH NAMES include-what-you-use iwyu)
if(IWYU_PATH)
message(STATUS "Found IWYU: ${IWYU_PATH}")
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${IWYU_PATH}")
else()
message(WARNING "IWYU not found, disabling")
endif()
endif()

# запуск

mkdir -p build && cd build
cmake -DENABLE_IWYU=ON ..
make 2> iwyu_initial.out

# Анализ результатов
wc -l iwyu_initial.out # Общее количество предупреждений
grep -c "should add" iwyu_initial.out # Пропущенные includes
grep -c "should remove" iwyu_initial.out # Лишние includes


Там есть еще нюансы с 3rd-party, которые мы вынесем за рамки обсуждения.

2️⃣ clang-tidy. Если у вас настроены проверки clang-tidy, то вам ничего не стоит подключить include what you use. Достаточно к проверкам добавить пункт misc-include-cleaner. В конфиге также можно настроить различные исключения, что мы также выносим за скобки обсуждения.

В целом, полезная вещь. Помогает меньше связывать модули друг с другом, а также потенциально уменьшает время компиляции.

Include what you use. Stay cool.

#tools #goodpractice
  • 👍 37
  • ❤ 11
  • 🔥 11
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →