What is the difference between #include <filename> and #include "filename" in C/C++ programming? How does the compiler search for header files differently when using angle brackets versus quotes?
The key difference between #include <filename> and #include "filename" in C/C++ lies in how the compiler searches for header files. Angle brackets (<>) instruct the compiler to search primarily in standard system directories, while double quotes ("") cause the compiler to first look in the same directory as the source file, then in standard directories. This distinction affects which version of a header gets included when local and system headers have the same name.
Contents
- Basic Search Path Differences
- Implementation-Defined Behavior
- Search Order and Priority
- Compiler Configuration and Custom Paths
- Conventions and Best Practices
- Edge Cases and Special Scenarios
- Practical Examples
Basic Search Path Differences
The fundamental difference between the two include directives is where the compiler begins its search for header files:
Angle Brackets (#include <filename>):
- Used for standard library headers (e.g.,
<iostream>,<vector>,<cmath>) - Compiler searches only in implementation-defined standard system directories
- These are typically directories like
/usr/includeon Unix systems or compiler-specific include directories - The search path is controlled by the compiler and system configuration
Double Quotes (#include "filename"):
- Used for local/project headers and third-party libraries
- Compiler first searches in the same directory as the source file containing the directive
- If not found locally, the compiler then searches in standard system directories
- This allows project-specific headers to be found without additional configuration
According to GCC documentation, “By default, the preprocessor looks for header files included by the quote form of the directive #include "file" first relative to the directory of the current file, and then in a preconfigured list of standard system directories.”
Implementation-Defined Behavior
It’s crucial to understand that the exact search behavior is implementation-defined - meaning each compiler vendor can define their own search algorithm, though most follow common patterns:
- Standard compliance: The C++ standard specifies that the search order is implementation-defined
- Common implementation: Most compilers search the current directory first for quoted includes, then standard paths
- Fallback behavior: Some implementations have a fallback mechanism where if a file isn’t found with quotes, it may be treated as if angle brackets were used
- Variations: Some compilers may search additional directories or have different search priorities
As noted in Stack Overflow discussions, “The search mechanism is implementation-defined either way. Using double quotes means that you intend to include a ‘source file’, while angle brackets mean you intend to include a ‘header’ which, as you say, may not be a file at all.”
Search Order and Priority
The search order differs significantly between the two include methods:
For #include <filename> (angle brackets):
- Searches in compiler-standard include directories (implementation-defined)
- Does not typically search the current directory
- May search directories specified via
-Iflags (command line) - May search directories specified via environment variables
For #include "filename" (double quotes):
- First searches in the directory of the source file containing the directive
- If not found locally, searches in standard system directories
- Then searches directories specified via
-Iflags - Finally searches directories specified via environment variables
From Stack Overflow, “#include <header_name>: Standard include file: look in standard paths (system include paths setup for the compiler) first. #include “header_name”: Look in current path first, then in include path (project specific lookup paths).”
Compiler Configuration and Custom Paths
Developers can control the include search path through several mechanisms:
Command Line Flags:
-I/path/to/include: Adds a directory to the include search path-I./include: Adds the local include directory- Multiple
-Iflags can be specified
Environment Variables:
C_INCLUDE_PATH: For C compiler include pathsCPLUS_INCLUDE_PATH: For C++ compiler include pathsINCLUDE: On Windows systems
Common Include Directories:
- Compiler installation directories (e.g.,
/usr/include,C:\MinGW\include) - Library-specific directories
- Project-specific directories
According to Stack Overflow, “C_INCLUDE_PATH=”/full/path/to/your/file/:C_INCLUDE_PATH" ## for C compiler CPLUS_INCLUDE_PATH="/full/path/to/your/file/:CPLUS_INCLUDE_PATH" ## for Cpp compiler export C_INCLUDE_PATH export CPLUS_INCLUDE_PATH"
And from GCC documentation, you can add custom search directories using -I flags.
Conventions and Best Practices
Following established conventions helps maintain code clarity and avoid conflicts:
Use Angle Brackets (<>) for:
- Standard library headers (
<iostream>,<vector>,<cmath>) - System headers provided by the compiler
- Third-party library headers when installed in system locations
- Headers that should be found via standard include paths
Use Double Quotes ("") for:
- Project-specific headers
- Headers in the same directory or subdirectories
- Third-party library headers when using local copies
- Headers that should be found relative to the source file
As stated in Stack Overflow, “So, by convention, you use the angle brackets for standard includes and the double quotes for everything else. This ensures that in the (not recommended) case in which you have a local header with the same name as a standard header, the right…”
Edge Cases and Special Scenarios
Several scenarios highlight the importance of understanding include search behavior:
Name Conflicts:
- If you have a local header named
vector.hand include<vector>, using quotes would include your local version instead of the standard library - This can lead to compilation errors or unexpected behavior
Fallback Behavior:
- Some compilers implement a fallback where if a quoted include isn’t found, they treat it as an angle bracket include
- According to GameDev.net, “if there is no other matching file found by the compiler in the “” path, the implementation is required to treat the include directive as a <> include directive.”
Relative Paths:
- You can use relative paths with quotes:
#include "../utils/helpers.h" - Angle brackets typically don’t support relative paths
Project Organization:
- Large projects often use quotes for internal headers and angle brackets for external dependencies
- This creates a clear distinction between project code and dependencies
Practical Examples
Example 1: Basic Usage
#include <iostream> // Standard library - searches system paths
#include "myclass.h" // Project header - searches current directory first
#include <vector> // Standard library
#include "../utils.h" // Relative path with quotes
Example 2: Compiler Configuration
# Using -I flag to add custom include path
g++ -I./include -I/usr/local/boost main.cpp
# Using environment variables
export CPLUS_INCLUDE_PATH=/path/to/my/includes:$CPLUS_INCLUDE_PATH
Example 3: Directory Structure
project/
├── src/
│ ├── main.cpp
│ └── utils/
│ └── helpers.h
├── include/
│ └── config.h
└── lib/
└── external/
└── library.h
In this structure:
#include "utils/helpers.h"would find the file in the same directory#include "config.h"would not be found in src/, might need-I../include#include <library.h>would need the external library in system paths or-I../lib/external
Sources
- Search Path (The C Preprocessor) - GCC Documentation
- Difference between angle bracket and double quotes while including header files in C++? - Stack Overflow
- What is the difference between #include
and #include “filename”? - Stack Overflow - Which directories does include statement search in C/C++? - Stack Overflow
- Include angle brackets vs. quote marks - GameDev.net
- How to tell g++ compiler where to search for include files? - Stack Overflow
- Defining the Include File Directory Search Path - TI Compiler Documentation
- r/cpp_questions on Reddit: Difference between quotation marks and angle brackets while including files
- How to make C/C++ compiler to look for headers in a user specified path - Stack Overflow
- Include Path Directory - Stack Overflow
Conclusion
The difference between #include <filename> and #include "filename" in C/C++ programming centers on search path behavior and intended use:
- Angle brackets prioritize system directories and are best suited for standard library headers
- Double quotes prioritize the current directory and are ideal for project-specific headers
- The search order is implementation-defined but follows predictable patterns across most compilers
- Proper usage prevents name conflicts and makes code more maintainable
For optimal results, follow these practices:
- Use angle brackets for standard library headers (
<iostream>,<vector>, etc.) - Use double quotes for local project headers and relative paths
- Configure custom include paths using
-Iflags or environment variables when needed - Be aware of potential name conflicts between local and system headers
- Document your project’s include conventions to maintain consistency
Understanding these differences helps prevent compilation issues and creates more maintainable code structure, especially as projects grow in complexity and include more dependencies.