The preprocessor runs in phase 4 of translation. It works on tokens, not on C++ syntax, and has no knowledge of types or scopes [cpp].
Directives
A directive is a line whose first token, after any white space, is #
[cpp.pre]. It ends at the next new-line, so a long directive needs a backslash at the
end of each continued line.
| Directive | Purpose | Since | Section |
|---|---|---|---|
#include | Inserts a header or source file | C++98 | [cpp.include] |
#define | Defines a macro | C++98 | [cpp.replace] |
#undef | Removes a macro definition | C++98 | [cpp.scope] |
#if | Starts a conditional group | C++98 | [cpp.cond] |
#ifdef, #ifndef | Tests whether a macro is defined | C++98 | [cpp.cond] |
#elif | Next alternative, with a condition | C++98 | [cpp.cond] |
#elifdef, #elifndef | Next alternative, testing a macro | C++23 | [cpp.cond] |
#else | Final alternative | C++98 | [cpp.cond] |
#endif | Ends a conditional group | C++98 | [cpp.cond] |
#line | Sets the presumed line number and file name | C++98 | [cpp.line] |
#error | Stops translation with a message | C++98 | [cpp.error] |
#warning | Issues a diagnostic and continues | C++23 | [cpp.error] |
#pragma | Implementation-defined behaviour | C++98 | [cpp.pragma] |
# alone | The null directive; does nothing | C++98 | [cpp.null] |
import, export import | Imports a header unit or module, treated by the preprocessor as a directive | C++20 | [cpp.import] |
module, export module | Begins a module unit, treated by the preprocessor as a directive | C++20 | [cpp.module] |
The operator _Pragma("text") (C++11) has the same effect as a
#pragma line, but can be produced by macro expansion
[cpp.pragma.op].
Conditional inclusion
if-group:
# if constant-expression new-line [group]
# ifdef identifier new-line [group]
# ifndef identifier new-line [group]
elif-group:
# elif constant-expression new-line [group]
# elifdef identifier new-line [group]
# elifndef identifier new-line [group]
defined-macro-expression:
defined identifier
defined ( identifier )
has-include-expression:
__has_include ( header-name )
__has_include ( header-name-tokens )
has-attribute-expression:
__has_cpp_attribute ( pp-tokens )
After macro expansion and the evaluation of defined,
__has_include and __has_cpp_attribute, every identifier and
keyword that is left, other than true and false, is replaced
by 0 [cpp.cond]. An undefined macro name therefore silently counts as 0. The expression uses
std::intmax_t or std::uintmax_t. It cannot use
sizeof, casts or enumerators, since the preprocessor does not know about
them.
#if defined(_WIN32) && !defined(NOMINMAX)
# define NOMINMAX
#endif
#ifdef FEATURE_X
void run_x();
#elifdef FEATURE_Y // C++23
void run_y();
#else
# error "No feature selected"
#endif
Including files
| Form | Search |
|---|---|
#include <name> | An implementation-defined set of places, which need not be files |
#include "name" | Implementation-defined, usually starting with the including file’s folder. If that fails, it is searched as if it were the <name> form |
#include MACRO | The macro is expanded, and the result must match one of the two forms above |
Nesting depth is limited only by the implementation. The standard’s minimum recommended
quantity is 256 levels (Annex B). #include does not check whether a file was
already included, which is why headers need
include guards.
__has_include
__has_include (C++17) is 1 if a matching header exists and 0 if not, using the same search as #include [cpp.cond]. It says only that a header can be found, and not that it will compile, or what it provides.
#if __has_include(<optional>)
# include <optional>
# define HAVE_OPTIONAL 1
#elif __has_include("legacy_optional.h")
# include "legacy_optional.h"
# define HAVE_OPTIONAL 2
#else
# define HAVE_OPTIONAL 0
#endif
__has_cpp_attribute
__has_cpp_attribute(name) gives a non-zero value if the attribute is
supported, and 0 if not. For standard attributes the value is the date in the table
below [cpp.cond].
| Attribute | Value |
|---|---|
assume | 202207L |
carries_dependency | 200809L |
deprecated | 201309L |
fallthrough | 201603L |
likely, unlikely | 201803L |
maybe_unused | 201603L |
no_unique_address | 201803L |
nodiscard | 201907L |
noreturn | 200809L |
Macros
control-line:
# define identifier replacement-list new-line
# define identifier lparen [identifier-list] ) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line
# undef identifier new-line
A macro name is an identifier, and may be a keyword. Defining or undefining a
predefined macro is undefined behaviour. A macro may be redefined only with an
identical definition; otherwise it must be #undef’d first [cpp.replace].
An object-like macro has no parameter list. For a function-like macro, the
( must follow the name immediately, with no space, or it becomes part of
the replacement.
Operators # and ##
| Operator | Effect | Section |
|---|---|---|
#param | Turns the argument’s tokens into a string literal, without macro-expanding it first | [cpp.stringize] |
a##b | Joins two tokens into one; the result must be a valid token | [cpp.concat] |
#define STR(x) #x
#define XSTR(x) STR(x)
#define VER 12
STR(VER) // "VER": the argument is not expanded before #
XSTR(VER) // "12": the outer macro expands it first
#define JOIN(a, b) a##b
JOIN(foo, 1) // foo1
Variadic macros
A macro whose parameter list ends in ... (C++11) receives its extra
arguments as __VA_ARGS__. __VA_OPT__(tokens) (C++20) expands
to its tokens only if the variable arguments are not empty, which solves the old
problem of a trailing comma [cpp.subst].
#define LOG(fmt, ...) printf(fmt __VA_OPT__(,) __VA_ARGS__)
LOG("hello\n"); // printf("hello\n")
LOG("x=%d\n", 42); // printf("x=%d\n", 42)
Rescanning
After replacement, the result is scanned again for more macros. A macro’s own name,
found during its own expansion, is not expanded again [cpp.rescan], so macros cannot
recurse. A macro name used without ( where a function-like macro is
expected is left alone.
Predefined macros
These are always defined [cpp.predefined].
| Macro | Value |
|---|---|
__cplusplus | The standard version; see below |
__DATE__ | Translation date as a string literal, "Mmm dd yyyy" |
__TIME__ | Translation time as a string literal, "hh:mm:ss" |
__FILE__ | Presumed name of the current source file |
__LINE__ | Presumed line number |
__STDC_HOSTED__ | 1 for a hosted implementation, 0 for a freestanding one |
__STDCPP_DEFAULT_NEW_ALIGNMENT__ | Alignment guaranteed by operator new (C++17) |
__STDCPP_FLOAT16_T__, __STDCPP_FLOAT32_T__, __STDCPP_FLOAT64_T__, __STDCPP_FLOAT128_T__, __STDCPP_BFLOAT16_T__ | 1 if the matching extended floating-point type is supported (C++23) |
Some are defined only conditionally:
| Macro | Meaning |
|---|---|
__STDC__, __STDC_VERSION__ | Implementation-defined whether defined, and with what value |
__STDC_ISO_10646__ | If defined, an integer literal of the form yyyymmL |
__STDC_MB_MIGHT_NEQ_WC__ | 1 if defined |
__STDCPP_THREADS__ | 1 if and only if a program can have more than one thread |
__func__ looks like a macro but is not: it is a predefined local variable of
a function, holding the function’s name [dcl.fct.def.general]. Names like
__FUNCTION__ and __PRETTY_FUNCTION__ are compiler
extensions.
Values of __cplusplus
| Standard | __cplusplus |
|---|---|
| C++98, C++03 | 199711L |
| C++11 | 201103L |
| C++14 | 201402L |
| C++17 | 201703L |
| C++20 | 202002L |
| C++23 | 202302L |
MSVC reports 199711L unless compiled with /Zc:__cplusplus,
regardless of the standard selected.
Feature-test macros
C++20 standardised macros that report which features a compiler supports. The value
is the year and month the feature reached its listed form, so later values mean more
complete support. Language macros are predefined, and start with
__cpp_ [cpp.predefined]. Library macros start with
__cpp_lib_ and are defined in <version> and in each header
that has the feature.
#if defined(__cpp_concepts) && __cpp_concepts >= 201907L
template<std::integral T> T twice(T v) { return v * 2; }
#else
template<class T> T twice(T v) { return v * 2; }
#endif
#include <version>
#ifdef __cpp_lib_format
# include <format>
#endif
The language macros in the C++23 working draft (N4950) are:
| Macro | Value |
|---|---|
__cpp_aggregate_bases | 201603L |
__cpp_aggregate_nsdmi | 201304L |
__cpp_aggregate_paren_init | 201902L |
__cpp_alias_templates | 200704L |
__cpp_aligned_new | 201606L |
__cpp_attributes | 200809L |
__cpp_auto_cast | 202110L |
__cpp_binary_literals | 201304L |
__cpp_capture_star_this | 201603L |
__cpp_char8_t | 202207L |
__cpp_concepts | 202002L |
__cpp_conditional_explicit | 201806L |
__cpp_constexpr | 202211L |
__cpp_constexpr_dynamic_alloc | 201907L |
__cpp_constexpr_in_decltype | 201711L |
__cpp_consteval | 202211L |
__cpp_constinit | 201907L |
__cpp_decltype | 200707L |
__cpp_decltype_auto | 201304L |
__cpp_deduction_guides | 201907L |
__cpp_delegating_constructors | 200604L |
__cpp_designated_initializers | 201707L |
__cpp_enumerator_attributes | 201411L |
__cpp_explicit_this_parameter | 202110L |
__cpp_fold_expressions | 201603L |
__cpp_generic_lambdas | 201707L |
__cpp_guaranteed_copy_elision | 201606L |
__cpp_hex_float | 201603L |
__cpp_if_consteval | 202106L |
__cpp_if_constexpr | 201606L |
__cpp_impl_coroutine | 201902L |
__cpp_impl_destroying_delete | 201806L |
__cpp_impl_three_way_comparison | 201907L |
__cpp_implicit_move | 202207L |
__cpp_inheriting_constructors | 201511L |
__cpp_init_captures | 201803L |
__cpp_initializer_lists | 200806L |
__cpp_inline_variables | 201606L |
__cpp_lambdas | 200907L |
__cpp_modules | 201907L |
__cpp_multidimensional_subscript | 202211L |
__cpp_named_character_escapes | 202207L |
__cpp_namespace_attributes | 201411L |
__cpp_noexcept_function_type | 201510L |
__cpp_nontype_template_args | 201911L |
__cpp_nontype_template_parameter_auto | 201606L |
__cpp_nsdmi | 200809L |
__cpp_range_based_for | 202211L |
__cpp_raw_strings | 200710L |
__cpp_ref_qualifiers | 200710L |
__cpp_return_type_deduction | 201304L |
__cpp_rvalue_references | 200610L |
__cpp_size_t_suffix | 202011L |
__cpp_sized_deallocation | 201309L |
__cpp_static_assert | 201411L |
__cpp_static_call_operator | 202207L |
__cpp_structured_bindings | 201606L |
__cpp_template_template_args | 201611L |
__cpp_threadsafe_static_init | 200806L |
__cpp_unicode_characters | 200704L |
__cpp_unicode_literals | 200710L |
__cpp_user_defined_literals | 200809L |
__cpp_using_enum | 201907L |
__cpp_variable_templates | 201304L |
__cpp_variadic_templates | 200704L |
__cpp_variadic_using | 201611L |
Pragmas in common use
The standard defines no pragmas. The meaning of each is up to the compiler, and an unrecognised one is ignored. These are widely supported extensions.
| Pragma | Effect |
|---|---|
#pragma once | Include the file only once per translation unit |
#pragma pack(n) | Sets the maximum alignment of class members |
#pragma GCC diagnostic, #pragma clang diagnostic | Controls warnings in GCC and Clang |
#pragma warning | Controls warnings in MSVC |