The Secret of #include in C++: <file> vs "file" — Speed and Optimization

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: One Small Detail That Could Cost You Seconds of Compilation

\n\n

Imagine: you're writing a C++ project. Work is in full swing, code is growing, folders with files are multiplying. And then you type #include again. As usual — in angle brackets? Or in quotes? And what difference does it make, after all? The compiler is smart, it will find it itself.

\n\n

Spoiler: it will find it. But not always quickly. And not always the file you intended. The question of the difference between #include <filename> and #include "filename" is one of the most popular on Stack Overflow (hundreds of thousands of views). And it's not just about syntactic sugar. It's a matter of compilation performance, control over dependencies, and ultimately, the quality of your code.

\n\n

In this article, we won't just list the rules. We'll look under the hood of the preprocessor, analyze real examples, and give practical advice on how to speed up your project's build. Let's go!

\n\n

How Does the Preprocessor Work? The Anatomy of the #include Directive

\n\n

Before the compiler sees your code, the preprocessor comes into play. Its job is to prepare the "source" for compilation. The #include directive is a command: "Take the contents of file X and insert it right here, instead of this line."

\n\n

Sounds simple. But the devil, as always, is in the details. Namely, in where the preprocessor looks for this file X.

\n\n

Angle Brackets: #include <filename>

\n

When you write #include <iostream>, the preprocessor goes searching exclusively along standard system paths. On Linux, this is usually /usr/include, /usr/local/include, and paths passed to the compiler via the -I flag (or /I in Visual Studio).

\n

Key point: the preprocessor does NOT look in the current project directory. Only in those folders that have been specified as "system" or "for include search."

\n

This is done on purpose: to avoid accidentally picking up a local file with the same name instead of the standard library.

\n\n

Double Quotes: #include "filename"

\n

With quotes, the story is more complex and interesting. The C++ standard (section 16.2) says: the behavior is implementation-defined. But in practice, 99% of compilers (GCC, Clang, MSVC) work on the same principle:

\n
    \n
  1. First, search in the directory where the including file itself is located (usually the current folder with the source file).
  2. \n
  3. Then, search along the same paths as for angle brackets (system + -I).
  4. \n
\n

That is, #include "myheader.h" will first check the folder with your main.cpp. Found it? Great. Didn't find it? It goes through the system list.

\n\n

Is This Just Knowledge or Real Optimization?

\n

"So what?" you might ask. "Computers are fast, what difference does it make where it searches?"

\n

There is a difference, and it comes from two factors: search speed and clarity of intent.

\n\n

Factor 1: File Search Speed

\n

In a small project (10-20 files), you won't notice a difference. But in a real enterprise product or game engine, the number of includes can exceed tens of thousands. Every time you write #include "some_system_lib.h", the preprocessor wastes extra time checking the current folder and all subfolders (depending on the implementation).

\n

A real-life example: imagine you have a project with 10,000 files. 20% of them use quotes for standard libraries. Each such include makes an extra system call stat() or access() in the current directory. These are microseconds, but in total for the entire project — real seconds of compilation.

\n\n

Using #include <iostream> instead of #include "iostream" guarantees that the search will start immediately from system paths, bypassing the local directory. This gives

Blogs

Book Recommendations