Preprocessor directives tell the preprocessor to perform specific actions before the compiler sees the source text. They begin with aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/MicrosoftDocs/cpp-docs/llms.txt
Use this file to discover all available pages before exploring further.
# sign as the first non-whitespace character on a line and are terminated by the end of that line (use a trailing backslash \ to continue a directive across multiple lines). Directives are distinct from C statements — they are processed in a completely separate phase of compilation and have no knowledge of types, scopes, or run-time values.
The number sign (#) must be the first non-white-space character on the line containing the directive. White-space characters can appear between the number sign and the first letter of the directive name.
#include — File Inclusion
The #include directive causes the preprocessor to replace the directive with the entire contents of the named file. It supports two forms that differ in where the preprocessor searches for the file:
Search Order
- Quoted Form
- Angle-Bracket Form
When you use
#include "filename", the preprocessor searches in this order:- The directory containing the file with the
#includestatement (the parent file’s directory). - Directories of currently open parent include files (grandparent directories), in reverse-open order.
- Directories specified by each
/Icompiler option (in order). - Directories specified by the
INCLUDEenvironment variable.
Nested Includes
Include files can be nested up to 10 levels deep. When a nested#include finishes processing, the preprocessor continues inserting the enclosing parent file:
Practical Example — Header Organization
#define and #undef — Macro Definition
The #define directive creates a macro, which the preprocessor uses to perform textual substitution throughout the source file. Once defined, every occurrence of the macro name is replaced with its token string.
Object-Like Macros
An object-like macro has no parameters. Use it to define symbolic constants:Removing a Definition with #undef
#undef removes a macro definition. After #undef, the identifier is no longer defined and can be redefined to a different value:
#if, #ifdef, #ifndef, #elif, #else, #endif — Conditional Compilation
Conditional directives allow portions of source code to be compiled only when specific conditions are true. They are the primary mechanism for platform portability, feature flags, and debug builds.
Basic Structure
#if, #ifdef, or #ifndef must be paired with a matching #endif.
#ifdef and #ifndef
#ifdef IDENTIFIER is equivalent to #if defined(IDENTIFIER). #ifndef IDENTIFIER is equivalent to #if !defined(IDENTIFIER).
Practical Examples
The defined Operator
The defined operator can be used inside #if and #elif expressions. It evaluates to 1 if the identifier is defined, 0 otherwise:
#line — Line Number and Filename Override
The #line directive overrides the line number (and optionally filename) that the compiler uses in diagnostic messages. It is typically generated by tools like parser generators, IDL compilers, and template engines so that errors point to the original source file rather than the generated file.
__LINE__ and __FILE__ predefined macros reflect the values set by #line:
#error and #warning — Compile-Time Diagnostics
#error
The #error directive emits a user-specified error message and terminates compilation. Use it to enforce build prerequisites:
#warning
The #warning directive emits a non-fatal diagnostic. Compilation continues after #warning:
The
#warning directive is a common extension. It is supported by MSVC, GCC, and Clang. The token-string argument to both #error and #warning is not subject to macro expansion — it is emitted literally.#pragma — Compiler-Specific Instructions
The #pragma directive passes implementation-specific instructions to the compiler. Unlike other preprocessor directives, pragmas are not removed from the translation unit — they are interpreted by the compiler itself. If the compiler does not recognize a pragma, it issues a warning and continues.
__pragma keyword (Microsoft-specific) and the standard _Pragma operator (C99+) allow pragmas inside macro definitions:
Line Continuation
Any preprocessor directive can span multiple source lines by placing a backslash (\) immediately before the newline:
See Also
- Macros (C/C++) — Macro expansion rules,
#,##,__VA_ARGS__, predefined macros - Pragma Directives —
#pragma once,#pragma warning,#pragma pack, and more - C Language Preprocessor Overview