The C preprocessor (CPP) is a text file processor that is used with C, C++ and other programming tools. The preprocessor provides for file inclusion (often header files), macro expansion, conditional compilation, and line control. Although named in association with C and used with C, the preprocessor capabilities are not inherently tied to the C language. It can be and is used to process other kinds of files.General-purpose text preprocessing with the C preprocessor. Featuring JavaScript

Languages C, C++, and Objective-C compilers provide a preprocessor capability, as it is required by the definition of each language. Some compilers provide extensions and deviations from the target language standard. Some provide options to control standards compliance. For instance, the GNU C preprocessor can be made more standards compliant by supplying certain command-line flags.

The C# programming language also allows for directives, though they are not read by a preprocessor and they cannot be used for creating macros, and are generally more intended for features such as conditional compilation. C# seldom requires the use of the directives, for example code inclusion does not require a preprocessor at all (as C# relies on a package/namespace system like Java, no code needs to be "included"). Similarly, F# and Visual J# are able to call these C# preprocessor directives.

The Haskell programming language also allows the usage of the C preprocessor.

Features of the preprocessor are encoded in source code as directives that start with #.

Although C++ source files are often named with a extension, that is an abbreviation for "C plus plus"; not C preprocessor.

Preprocessor directives The following languages have the following accepted directives. C/C++ The following tokens are recognised by the preprocessor in the context of preprocessor directives.

#if #elif #else #endif #ifdef #ifndef #elifdef #elifndef #define #undef #include #embed #line #error #warning #pragma defined (follows a conditional directive; not actually a directive, but rather an operator) __has_include (operator) __has_cpp_attribute (operator) __has_c_attribute (operator) __has_embed (operator)

Until C++26, the C++ keywords import, export, and module were partially handled by the preprocessor as well.

The Haskell programming language also accepts C preprocessor directives, which is invoked by writing {-# LANGUAGE CPP #-} at the top of the file. The accepted preprocessor directives align with those in standard C/C++.

C# Although C#, F# and Visual J# do not have a separate preprocessor, these directives are processed as if there were one.

#nullable #if #elif #else #endif #define #undef #region #endregion #error #warning #line #pragma

C# does not use a preprocessor to handle these directives, and thus they are not handled or removed by a preprocessor, but rather directly read by the C# compiler as a feature of the language.

Objective-C The following tokens are recognised by the preprocessor in the context of preprocessor directives.

#if #elif #else #endif #ifdef #ifndef #define #undef #include #import #error #pragma defined

Swift The following tokens, called "compiler directives", are detected by the compiler. They are not entirely the same as C preprocessor directives, but have the same structure and syntax.

#if arch(...) canImport(...) compiler(...) hasAttribute(...) hasFeature(...) os(...) swift(...) targetEnvironment(...) #elseif #else #endif #available #unavailable #error #warning #file #fileID #filePath #line #column #function #dsohandle #sourceLocation #selector #keyPath #colorLiteral #imageLiteral #fileLiteral #stringify #externalMacro

History The preprocessor was introduced to C around 1973 at the urging of Alan Snyder and also in recognition of the usefulness of the file inclusion mechanisms available in BCPL and PL/I. The first version offered file inclusion via #include and parameterless string replacement macros via #define. It was extended shortly after, firstly by Mike Lesk and then by John Reiser, to add arguments to macros and to support conditional compilation.

The C preprocessor was part of a long macro-language tradition at Bell Labs, which was started by Douglas Eastwood and Douglas McIlroy in 1959.

Phases Preprocessing is defined by the first four (of eight) phases of translation specified in the C Standard.

Trigraph replacement: The preprocessor replaces trigraph sequences with the characters they represent. This phase was removed in C23 following the steps of C++17. Line splicing: Physical source lines that are continued with escaped newline sequences are spliced to form logical lines. Tokenization: The preprocessor breaks the result into preprocessing tokens and whitespace. It replaces comments with whitespace. Macro expansion and directive handling: Preprocessing directive lines, including file inclusion and conditional compilation, are executed. The preprocessor simultaneously expands macros and, since the 1999 version of the C standard, handles _Pragma operators.

Features

File inclusion There are two directives in the C preprocessor for including contents of files: #include, used for directly including the contents of a file in-place (typically containing code of some kind) #embed, used for directly including or embedding the contents of a binary resource in-place

Code inclusion To include the content of one file into another, the preprocessor replaces a line that starts with #include with the content of the file specified after the directive. The inclusion may be logical in the sense that the resulting content may not be stored on disk and certainly is not overwritten to the source file. The file being included need not contain any sort of code, as this directive will copy the contents of whatever file is included in-place, but the most typical use of #include is to include a header file (or in some rarer cases, a source file).

In the following example code, the preprocessor replaces the line #include <stdio.h> with the content of the standard library header file named '' in which the function printf() and other symbols are declared.

#include <stdio.h>

int main(void) { printf("Hello, World!\n"); return 0; }

In this case, the file name is enclosed in angle brackets to denote that it is a system file. For a file in the codebase being built, double-quotes are used instead. The preprocessor may use a different search algorithm to find the file based on this distinction.

For C, a header file is usually named with a extension. In C++, the convention for file extension varies with common extensions and . But the preprocessor includes a file regardless of the extension. In fact, sometimes code includes or files.

To prevent including the same file multiple times, which often leads to a compiler error, a header file typically contains an guard or if supported by the preprocessor to prevent multiple inclusion.

Binary resource inclusion C23 and C++26 introduce the #embed directive for binary resource inclusion, which allows including the content of a binary file into a source even if it is not valid C code. This allows binary resources (like images) to be included into a program without requiring processing by external tools like xxd -i and without the use of string literals, which have a length limit on MSVC. Similarly to xxd -i, the directive is replaced by a comma separated list of integers corresponding to the data of the specified resource. More precisely, if an array of type unsigned char is initialized using an #embed directive, the result is the same as-if the resource was written to the array using fread (unless a parameter changes the embed element width to something other than CHAR_BIT). Apart from the convenience, #embed is also easier for compilers to handle, since they are allowed to skip expanding the directive to its full form due to the as-if rule.

The supported parameters are: limit offset prefix suffix if_empty

The file to embed is specified the same as for #include either with brackets or double quotes. The directive also allows certain parameters to be passed to it to customize its behavior. The C standard defines some parameters and implementations may define additional. The limit parameter is used to limit the width of the included data. It is mostly intended to be used with "infinite" files like urandom. The prefix and suffix parameters allow for specifying a prefix and suffix to the embedded data. Finally, the if_empty parameter replaces the entire directive if the resource is empty. In C, all standard parameters can be surrounded by double underscores, just like standard attributes on C23, for example __prefix__ is interchangeable with prefix, however this is not the case in C++. Implementation-defined parameters use a form similar to attribute syntax (e.g., vendor::attr) but without the square brackets. While all standard parameters require an argument to be passed to them (e.g., limit requires a width), this is generally optional and even the set of parentheses can be omitted if an argument is not required, which might be the case for some implementation-defined parameters. C++29 adds an offset parameter to #embed.

constexpr char ICON_DISPLAY_DATA[] = { #embed "art.png"

// specify any type which can be initialized form integer constant expressions will do constexpr char RESET_BLOB[] = { #embed "data.bin"

// attributes work just as well alignas(8) constexpr char ALIGNED_DATA_STRING[] = { #embed "attributes.xml"

int main() { return #embed </dev/urandom> limit(1)

Conditional compilation Conditional compilation is supported via the if-else core directives #if, #else, #elif, and #endif and with contraction directives #ifdef and #ifndef, which stand for #if defined(...) and #if !defined(...), respectively. In the following example code, the printf() call is only included for compilation if VERBOSE is defined.

#ifdef VERBOSE printf("trace message"); #endif

The following demonstrates more complex logic:

#if !(defined __LP64__ || defined __LLP64__) || defined _WIN32 && !defined _WIN64 // code for a 32-bit system #else // code for a 64-bit system #endif

Macro string replacement

Object-like A macro specifies how to replace text in the source code with other text. An object-like macro defines a token that the preprocessor replaces with other text. It does not include parameter syntax and therefore cannot support parameterization. The following macro definition associates the text 1 / 12 with the token VALUE:

#define VALUE 1 / 12

Function-like A function-like macro supports parameters, although the parameter list can be empty. The following macro definition associates the expression (A + B) with the token ADD that has parameters A and B.

#define ADD(A, B) (A + B)

A function-like macro declaration cannot have whitespace between the token and the first, opening parenthesis. If whitespace is present, the macro is interpreted as object-like with everything starting at the first parenthesis included in the replacement text.

Expansion The preprocessor replaces each token of the code that matches a macro token with the associated replacement text in what is known as macro expansion. Note that text of string literals and comments is not parsed as tokens and is therefore ignored for macro expansion. For a function-like macro, the macro parameters are also replaced with the values specified in the macro reference. For example, ADD(VALUE, 2) expands to 1 / 12 + 2.

Variadic

A variadic macro (introduced with C99) accepts a varying number of arguments, which is particularly useful when wrapping functions that accept a variable number of parameters, such as printf.

Order of expansion Function-like macro expansion occurs in the following stages: