TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #813 5.67K
#include <filename> vs #include "filename"
#новичкам

Тот нюанс, который зеленые программисты С++ впитывают из окружающей среды, но зачастую не понимают его деталей.

Дано: файл, который нужно включить в проект. Задача: определить, включать его через треугольные скобки или кавычки. Какой подход выбрать?

Стандарт нам дает отписку, что поведение при обоих подходах implementation defined, поэтому надо смотреть на то, как ведут себя большинство компиляторов.

Для начала: #include - это директива препроцессора. На месте этой директивы на этапе препроцессинга вставляется тело включаемого файла. Но для того, чтобы вставить текст файла, его надо в начале найти. И вот здесь главное различие.

У компилятора есть 2 вида путей, где он ищет файлы - системные директории и предоставленные юзером через опцию компиляции -I.

Так вот #include <filename> в начале ищет файл в системных директориях. Например, в линуксе хэдэры устанавливаемых библиотек могут оказаться в директориях /usr/include/, /usr/local/include/ или /usr/include/x86_64-linux-gnu/(на x86 системах).

А #include "filename" в начале ищет файл в текущей директории и в директориях, предоставленных через опцию компиляции.

В конце концов, обычно, в обоих случаях все известные компилятору директории будут просмотрены на наличие подходящего файла, пока он не будет найден. Вопрос только в порядке поиска.

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

✅ Используем #include <filename> для включения стандартных файлов и хэдэров сторонних библиотек. Так как они скорее всего установлены по стандартным директориям, логично именно там начинать их поиск.

#include <stdio.h> // Стандартный заголовочник
#include <curl/curl.h> // Заголовочник из системной директории

int main(void) {
CURL *curl = curl_easy_init();
if(curl) {
printf("libcurl version: %s\n", curl_version());
curl_easy_cleanup(curl);
}
return 0;
}


✅ Используем #include "filename" для включения заголовочных файлов своего проекта. Препроцессор будет сначала искать эти файлы там, где вы ему об этом явно укажите с помощью опций.

// include/mylib.hpp - объявляем функцию из нашего проекта
#pragma once
void print_hello();

// src/main.cpp - используем локальный заголовочник через " "
#include <iostream> // Системный заголовочник
#include "mylib.hpp" // Заголовочник локального проекта, ищем в указанных путях

int main() {
print_hello();
return 0;
}

void print_hello() {
std::cout << "Hello from my project!\n";
}

// компиляция: g++ -Iinclude/ src/main.cpp -o my_program -std=c++17


See the difference. Stay cool.

#cppcore #compiler
  • ❤ 63
  • 👍 26
  • 🔥 10
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 →