Preprocessor

From cppreference.com
< cpp
 
 
C++ language
General topics
Preprocessor
Comments
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++20)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
decltype (C++11)
auto (C++11)
alignas (C++11)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Implicit conversions - Explicit conversions
static_cast - dynamic_cast
const_cast - reinterpret_cast
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static
Special member functions
Templates
Miscellaneous
 
 

The preprocessor is executed at translation phase 4, before the compilation. The result of preprocessing is a single file which is then passed to the actual compiler.

Directives

The preprocessing directives control the behavior of the preprocessor. Each directive occupies one line and has the following format:

  • # character
  • preprocessing instruction (one of define, undef, include, if, ifdef, ifndef, else, elif, elifdef, elifndef (since C++23), endif, line, error, pragma) [1]
  • arguments (depends on the instruction)
  • line break

The null directive (# followed by a line break) is allowed and has no effect.

The module and import directives are also preprocessing directives.

(since C++20)

Preprocessing directives must not come from macro expansion.

#define EMPTY
EMPTY   #   include <file.h> // not a preprocessing directive

Capabilities

The preprocessor has the source file translation capabilities:

  • conditionally compile of parts of source file (controlled by directive #if, #ifdef, #ifndef, #else, #elif, #elifdef, #elifndef (since C++23), and #endif).
  • replace text macros while possibly concatenating or quoting identifiers (controlled by directives #define and #undef, and operators # and ##)
  • include other files (controlled by directive #include and checked with __has_include (since C++17))
  • cause an error (controlled by directive #error)

The following aspects of the preprocessor can be controlled:

  • implementation defined behavior (controlled by directive #pragma and operator _Pragma (since C++11)). In addition, some compilers support (to varying degrees) the operator __pragma as a non-standard extension.
  • file name and line information available to the preprocessor (controlled by directive #line)

Footnotes

  1. These are the directives defined by the standard. The standard does not define behavior for other directives: they might be ignored, have some useful meaning, or cause a compile-time error. Even if otherwise ignored, they are removed from the source code when the preprocessor is done. A common non-standard extension is the directive #warning which emits a user-defined message during compilation.

See also