{{Short description|Text processor used with C and C++ and other programming tools}} {{Use dmy dates|date=June 2023}} {{multiple issues| {{how-to|date=February 2013}} {{more footnotes needed|date=March 2015}} }} 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.<ref>[https://gist.github.com/djedr/7d21eac05ce2bbbca29b29d532a1fbe4 General-purpose text preprocessing with the C preprocessor. Featuring JavaScript]</ref>
== 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.<ref name="gnu-cpp-overview"> {{cite web |title=The C Preprocessor: Overview |url=https://gcc.gnu.org/onlinedocs/cpp/Overview.html |access-date=17 July 2016 }}</ref>
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.<ref>{{cite web|url=https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives|title=C# preprocessor directives|date=14 January 2022 |publisher=Microsoft}}</ref> 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 <code>#</code>.
Although C++ source files are often named with a <code>.cpp</code> 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. {{div col|colwidth=15em}} * <code>#if</code> * <code>#elif</code> * <code>#else</code> * <code>#endif</code> * <code>#ifdef</code> * <code>#ifndef</code> * <code>#elifdef</code> * <code>#elifndef</code> * <code>#define</code> * <code>#undef</code> * <code>#include</code> * <code>#embed</code> * <code>#line</code> * <code>#error</code> * <code>#warning</code> * <code>#pragma</code> * <code>defined</code> (follows a conditional directive; not actually a directive, but rather an operator) * <code>__has_include</code> (operator) * <code>__has_cpp_attribute</code> (operator) * <code>__has_c_attribute</code> (operator) * <code>__has_embed</code> (operator) {{div col end}}
Until C++26, the C++ keywords <code>import</code>, <code>export</code>, and <code>module</code> were partially handled by the preprocessor as well.
The Haskell programming language also accepts C preprocessor directives, which is invoked by writing <syntaxhighlight lang="Haskell" inline>{-# LANGUAGE CPP #-}</syntaxhighlight> at the top of the file. The accepted preprocessor directives align with those in standard C/C++.
=== C# === Although C#, F#<ref>{{Cite web|title=Compiler Directives|url=https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/compiler-directives|website=learn.microsoft.com|publisher=Microsoft Learn|date=30 July 2025}}</ref> and Visual J# do not have a separate preprocessor, these directives are processed as if there were one. {{div col|colwidth=15em}} * <code>#nullable</code> * <code>#if</code> * <code>#elif</code> * <code>#else</code> * <code>#endif</code> * <code>#define</code> * <code>#undef</code> * <code>#region</code> * <code>#endregion</code> * <code>#error</code> * <code>#warning</code> * <code>#line</code> * <code>#pragma</code> {{div col end}}
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. {{div col|colwidth=15em}} * <code>#if</code> * <code>#elif</code> * <code>#else</code> * <code>#endif</code> * <code>#ifdef</code> * <code>#ifndef</code> * <code>#define</code> * <code>#undef</code> * <code>#include</code> * <code>#import</code> * <code>#error</code> * <code>#pragma</code> * <code>defined</code> {{div col end}}
=== 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. {{div col|colwidth=15em}} * <code>#if</code> ** <code>arch(...)</code> ** <code>canImport(...)</code> ** <code>compiler(...)</code> ** <code>hasAttribute(...)</code> ** <code>hasFeature(...)</code> ** <code>os(...)</code> ** <code>swift(...)</code> ** <code>targetEnvironment(...)</code> * <code>#elseif</code> * <code>#else</code> * <code>#endif</code> * <code>#available</code> * <code>#unavailable</code> * <code>#error</code> * <code>#warning</code> * <code>#file</code> * <code>#fileID</code> * <code>#filePath</code> * <code>#line</code> * <code>#column</code> * <code>#function</code> * <code>#dsohandle</code> * <code>#sourceLocation</code> * <code>#selector</code> * <code>#keyPath</code> * <code>#colorLiteral</code> * <code>#imageLiteral</code> * <code>#fileLiteral</code> * <code>#stringify</code> * <code>#externalMacro</code> {{div col end}}
== 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 <code>#include</code> and parameterless string replacement macros via <code>#define</code>. It was extended shortly after, firstly by Mike Lesk and then by John Reiser, to add arguments to macros and to support conditional compilation.<ref>{{harvtxt|Ritchie|1993}}</ref>
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.<ref name="BellSAP">{{cite encyclopedia |title=Bell SAP – SAP with conditional and recursive macros |encyclopedia=HOPL: Online Historical Encyclopaedia of Programming Languages |url=https://hopl.info/showlanguage.prx?exp=5635 |access-date=4 October 2020 |archive-date=14 October 2023 |archive-url=https://web.archive.org/web/20231014100551/https://hopl.info/showlanguage.prx?exp=5635 |url-status=dead }}</ref>
== 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 <code>_Pragma</code> operators.
== Features ==
=== File inclusion === There are two directives in the C preprocessor for including contents of files: * <code>#include</code>, used for directly including the contents of a file in-place (typically containing code of some kind) * <code>#embed</code>, 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 <code>#include</code> 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 <code>#include</code> is to include a header file (or in some rarer cases, a source file).
In the following example code, the preprocessor replaces the line <code>#include <stdio.h></code> with the content of the standard library header file named '{{mono|stdio.h}}' in which the function <code>printf()</code> and other symbols are declared.
<syntaxhighlight lang="cpp"> #include <stdio.h>
int main(void) { printf("Hello, World!\n"); return 0; } </syntaxhighlight>
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 <code>.h</code> extension. In C++, the convention for file extension varies with common extensions <code>.h</code> and <code>.hpp</code>. But the preprocessor includes a file regardless of the extension. In fact, sometimes code includes <code>.c</code> or <code>.cpp</code> files.
To prevent including the same file multiple times, which often leads to a compiler error, a header file typically contains an {{mono|#include}} guard or if supported by the preprocessor {{mono|#pragma once}} to prevent multiple inclusion.
==== Binary resource inclusion ==== C23 and C++26 introduce the <code>#embed</code> 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.<ref>{{cite web |title=WG14-N3017 : #embed – a scannable, tooling-friendly binary resource inclusion mechanism |url=https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3017.htm |website=open-std.org |archive-url=https://web.archive.org/web/20221224045304/https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3017.htm |archive-date=24 December 2022 |date=2022-06-27 |url-status=live}}</ref><ref>{{Cite web|title=#embed - a scannable, tooling-friendly binary resource inclusion mechanism|url=https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p1967r14.html|website=open-std.org }}</ref> This allows binary resources (like images) to be included into a program without requiring processing by external tools like <code>xxd -i</code> and without the use of string literals, which have a length limit on MSVC. Similarly to <code>xxd -i</code>, 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 {{code|unsigned char}} is initialized using an <code>#embed</code> directive, the result is the same as-if the resource was written to the array using <code>fread</code> (unless a parameter changes the embed element width to something other than <code>CHAR_BIT</code>). Apart from the convenience, <code>#embed</code> is also easier <!--than what?--> for compilers to handle, since they are allowed to skip expanding the directive to its full form due to the as-if rule.
The file to embed is specified the same as for <code>#include</code> {{endash}} 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 <code>limit</code> parameter is used to limit the width of the included data. It is mostly intended to be used with "infinite" files like urandom. The <code>prefix</code> and <code>suffix</code> parameters allow for specifying a prefix and suffix to the embedded data. Finally, the <code>if_empty</code> parameter replaces the entire directive if the resource is empty. All standard parameters can be surrounded by double underscores, just like standard attributes on C23, for example <code>__prefix__</code> is interchangeable with <code>prefix</code> <!-- This will not be the case in C++ once the feature is ported over. See: P1967-->. Implementation-defined parameters use a form similar to attribute syntax (e.g., <code>vendor::attr</code>) 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.
<syntaxhighlight lang="cpp"> const unsigned char iconDisplayData[] = { #embed "art.png" };
// specify any type which can be initialized form integer constant expressions will do const char resetBlob[] = { #embed "data.bin" };
// attributes work just as well alignas(8) const signed char alignedDataString[] = { #embed "attributes.xml" };
int main() { return #embed </dev/urandom> limit(1) ; } </syntaxhighlight>
=== Conditional compilation === Conditional compilation is supported via the if-else core directives <code>#if</code>, <code>#else</code>, <code>#elif</code>, and <code>#endif</code> and with contraction directives <code>#ifdef</code> and <code>#ifndef</code>, which stand for {{code|#if defined(...)}} and {{code|#if !defined(...)}}, respectively. In the following example code, the <code>printf()</code> call is only included for compilation if <code>VERBOSE</code> is defined.
<syntaxhighlight lang="cpp"> #ifdef VERBOSE printf("trace message"); #endif </syntaxhighlight>
The following demonstrates more complex logic:
<syntaxhighlight lang="cpp"> #if !(defined __LP64__ || defined __LLP64__) || defined _WIN32 && !defined _WIN64 // code for a 32-bit system #else // code for a 64-bit system #endif </syntaxhighlight>
=== 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":
<syntaxhighlight lang="cpp"> #define VALUE 1 / 12 </syntaxhighlight>
==== 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".
<syntaxhighlight lang="cpp"> #define ADD(A, B) (A + B) </syntaxhighlight>
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, <code>ADD(VALUE, 2)</code> expands to <code>1 / 12 + 2</code>.
==== Variadic ==== {{Main|Variadic macro}} 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 <code>printf</code>.
==== Order of expansion ==== ''Function-like'' macro expansion occurs in the following stages:
# Stringification operations are replaced with the textual representation of their argument's replacement list (without performing expansion). # Parameters are replaced with their replacement list (without performing expansion). # Concatenation operations are replaced with the concatenated result of the two operands (without expanding the resulting token). # Tokens originating from parameters are expanded. # The resulting tokens are expanded as normal.
This may produce surprising results:
<syntaxhighlight lang="cpp"> #define HE HI #define LLO _THERE #define HELLO "HI THERE" #define CAT(a,b) a##b #define XCAT(a,b) CAT(a,b) #define CALL(fn) fn(HE,LLO) CAT(HE, LLO) // "HI THERE", because concatenation occurs before normal expansion XCAT(HE, LLO) // HI_THERE, because the tokens originating from parameters ("HE" and "LLO") are expanded first CALL(CAT) // "HI THERE", because this evaluates to CAT(a,b) </syntaxhighlight>
===Undefine macro===
A macro definition can be removed from the preprocessor context via <code>#undef</code> such that subsequent reference to the macro token will not expand. For example:
<syntaxhighlight lang="cpp"> #define VALUE 15
// do stuff with VALUE...
#undef VALUE // token 'VALUE' no longer expands from here... </syntaxhighlight>
===Predefined macros===
The preprocessor provides some macro definitions automatically. The C standard specifies that <code>__FILE__</code> expands to the name of the file being processed and <code>__LINE__</code> expands to the number of the line that contains the directive. The following macro, <code>DEBUGPRINT</code>, formats and prints a message with the file name and line number.
<syntaxhighlight lang="cpp"> #define DEBUGPRINT(_fmt, ...) printf("[%s:%d]: " _fmt, __FILE__, __LINE__, __VA_ARGS__) </syntaxhighlight>
For the example code below that is on line 30 of file <code>util.c</code> and for count 123, the output is: <code>[util.c:30]: count=123</code>.
<syntaxhighlight lang="cpp"> DEBUGPRINT("count=%d\n", count); </syntaxhighlight>
The first C Standard specified that <code>__STDC__</code> expand to "1" if the implementation conforms to the ISO standard and "0" otherwise and that <code>__STDC_VERSION__</code> expand to a numeric literal specifying the version of the standard supported by the implementation. Standard C++ compilers support the <code>__cplusplus</code> macro. Compilers running in non-standard mode must not set these macros or must define others to signal the differences.
Other standard macros include <code>__DATE__</code>, the current date, and <code>__TIME__</code>, the current time.
The second edition of the C Standard, C99, added support for <code>__func__</code>, which contains the name of the function definition within which it is contained, but because the preprocessor is agnostic to the grammar of C, this must be done in the compiler itself using a variable local to the function.
One little-known usage pattern of the C preprocessor is known as X-Macros.<ref name="X_macros">[http://liw.iki.fi/liw/texts/cpp-trick.html Wirzenius, Lars. C "Preprocessor Trick For Implementing Similar Data Types". Retrieved January 9, 2011]</ref><ref>{{cite journal | last = Meyers | first = Randy |date=May 2001 | title = The New C: X Macros | journal = Dr. Dobb's Journal | url = http://www.ddj.com/cpp/184401387 | access-date = 1 May 2008 }}</ref><ref>{{cite journal | last = Beal | first = Stephan |date=August 2004 | title = Supermacros | url = http://wanderinghorse.net/computing/papers/#supermacros | access-date = 27 October 2008 }}</ref> An X-Macro is a header file. Commonly, these use the extension <code>.def</code> instead of the traditional <code>.h</code> . This file contains a list of similar macro calls, which can be referred to as "component macros." The include file is then referenced repeatedly.
Many compilers define additional, non-standard macros. A common reference for these macros is the [https://predef.sourceforge.net/ Pre-defined C/C++ Compiler Macros project], which lists "various pre-defined compiler macros that can be used to identify standards, compilers, operating systems, hardware architectures, and even basic run-time libraries at compile-time."
Most compilers targeting Microsoft Windows implicitly define <code>_WIN32</code>.<ref>[http://msdn.microsoft.com/en-us/library/b0084kay.aspx List of predefined ANSI C and Microsoft C++ implementation macros.]</ref> This allows code, including preprocessor commands, to compile only when targeting Windows systems. A few compilers define <code>WIN32</code> instead. For such compilers that do not implicitly define the <code>_WIN32</code> macro, it can be specified on the compiler's command line, using <code>-D_WIN32</code>.
<syntaxhighlight lang="cpp"> #ifdef __unix__ // __unix__ is usually defined by compilers targeting Unix systems #include <unistd.h> #elifdef _WIN32 // _WIN32 is usually defined by compilers targeting 32 or 64 bit Windows systems #include <windows.h> #endif
#ifdef __linux__ #define CURRENT_PLATFORM "Linux" #elifdef __APPLE__ #define CURRENT_PLATFORM "Apple" #elifdef _WIN32 #define CURRENT_PLATFORM "Windows" #else #define CURRENT_PLATFORM "Other" #endif </syntaxhighlight>
The example code tests if a macro <code>__unix__</code> is defined. If it is, the file <code><unistd.h></code> is then included. Otherwise, it tests if a macro <code>_WIN32</code> is defined instead. If it is, the file <code><windows.h></code> is then included. Similarly, depending on which macro is defined, it defines <code>CURRENT_PLATFORM</code> to be a string with the name of the platform of the system.
===Line control=== The values of the predefined macros <code>__FILE__</code> and <code>__LINE__</code> can be set for a subsequent line via the <code>#line</code> directive. In the code below, <code>__LINE__</code> expands to 314 and <code>__FILE__</code> to "pi.c".
<syntaxhighlight lang="cpp"> #line 314 "pi.c" printf("line=%d file=%s\n", __LINE__, __FILE__); </syntaxhighlight>
===Operators=== The preprocessor is capable of interpreting operators and evaluating very basic expressions, such as integer constants, arithmetic operators, comparison operators, logical operators, bitwise operations, the <code>defined</code> operator, and the <code>#</code> stringificafion operator. This allows the preprocessor to make evaluations such as: <syntaxhighlight lang="cpp"> // if X equals 10, the preprocessor sees #if 10 == 10 #if X == 10 </syntaxhighlight>
====Defined operator==== While the '''defined operator''', denoted by <code>defined</code> is not a directive in its own right, if it is read within a directive, it is interpreted by the preprocessor and determines whether a macro has been defined.
The following are both accepted ways of invoking the <code>defined</code> operator. <syntaxhighlight lang="cpp"> #if defined(MY_MACRO) #if defined MY_MACRO </syntaxhighlight>
====Token stringification operator==== The '''stringification operator''' (a.k.a. stringizing operator), denoted by <code>#</code> converts a token into a string literal, escaping any quotes or backslashes as needed. For definition:
<syntaxhighlight lang="cpp"> #define STR(s) #s </syntaxhighlight>
<code>STR(\n)</code> expands to <code>"\n"</code> and <code>STR(p = "foo\n";)</code> expands to <code>"p = \"foo\\n\";"</code>.
If stringification of the expansion of a macro argument is desired, two levels of macros must be used. For definition:
<syntaxhighlight lang="cpp"> #define XSTR(s) STR(s) #define STR(s) #s #define FOO 4 </syntaxhighlight>
<code>STR(FOO)</code> expands to {{mono|"FOO"}} and <code>XSTR(FOO)</code> expands to {{mono|"4"}}.
A macro argument cannot be combined with additional text and then stringified. However, a series of adjacent string literals and stringified arguments, also string literals, are concatenated by the C compiler.
====Token concatenation==== The '''token pasting operator''', denoted by <code>##</code>, concatenates two tokens into one. For example, this can be used to simplify boilerplate by generating getter and setter methods, similar those of ''Project Lombok'' (in Java).<ref>{{Cite web|title=@Getter and @Setter|url=https://projectlombok.org/features/GetterSetter|publisher=Project Lombok|author=Project Lombok|access-date=22 April 2026|website=projectlombok.org}}</ref> <syntaxhighlight lang="cpp"> #define GETTER(type, method, name) \ type get##method() const noexcept { \ return this->name; \ }
#define SETTER(type, method, name) \ void set##method(type value) noexcept { \ this->name = value; \ }
using std::string;
class Student { private: string name; int age; double gpa; public: // constructors...
GETTER(string, Name, name) SETTER(string, Name, name) GETTER(int, Age, age) SETTER(int, Age, age) GETTER(double, Gpa, gpa) SETTER(double, Gpa, gpa)
// more methods... }; </syntaxhighlight>
=== Abort === Processing can be aborted via the <code>#error</code> directive. For example:
<syntaxhighlight lang="cpp"> #if RUBY_VERSION == 190 #error Ruby version 1.9.0 is not supported #endif </syntaxhighlight>
=== Warning === As of C23<ref name="N3096">{{cite web |title=WG14-N3096 : Draft for ISO/IEC 9899:2023 |url=https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf |website=open-std.org |archive-url=https://web.archive.org/web/20230402172459/https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf |archive-date=2 April 2023 |date=1 April 2023 |url-status=live}}</ref> and C++23,<ref>{{Cite web|title=Working Draft, Standard for Programming Language C++|url=https://open-std.org/JTC1/SC22/WG21/docs/papers/2023/n4944.pdf|date=2023-03-22}}</ref> a warning directive, <code>#warning</code>, to print a message without aborting is provided. Some typical uses are to warn about the use of deprecated functionality. For example:
Prior to C23 and C++23, this directive existed in many compilers as a non-standard feature, such as the C compilers by GNU, Intel, Microsoft and IBM. Because it was non-standard, the warning macro had varying forms: <syntaxhighlight lang="c"> // GNU, Intel and IBM #warning "Do not use ABC, which is deprecated. Use XYZ instead."
// Microsoft #pragma message("Do not use ABC, which is deprecated. Use XYZ instead.") </syntaxhighlight>
==Non-standard features ==
=== <code>#pragma</code> === The <code>#pragma</code> directive is defined by standard languages, but with little or no requirements for syntax after its name so that compilers are free to define subsequent syntax and associated behavior. For instance, a pragma is often used to allow suppression of error messages, manage heap and stack debugging and so on.
C99 introduced a few standard pragmas, taking the form <code>#pragma STDC ...</code>, which are used to control the floating-point implementation. The alternative, macro-like form {{code|_Pragma(...)}} was also added.
One of the most popular uses of the <code>#pragma</code> directive is {{mono|#pragma once}}, which behaves the same way an {{mono|#include}} guard would, condensed into a single directive placed at the top of the file. Despite being non-standard, it is supported by most compilers.
=== Trigraphs === Many implementations do not support trigraphs or do not replace them by default.
=== Assertion === Some Unix preprocessors provided an assertion feature {{endash}} which has little similarity to standard library assertions.<ref>[https://gcc.gnu.org/onlinedocs/cpp/Obsolete-Features.html GCC Obsolete features]</ref>
=== <code>#include_next</code> === GCC provides <code>#include_next</code> for chaining headers of the same name.<ref>{{Cite web|url=https://gcc.gnu.org/onlinedocs/cpp/Wrapper-Headers.html|title = Wrapper Headers (The C Preprocessor)}}</ref>
For example, if one overrides the file <code><stdio.h></code>, trying to include the standard library <code><stdio.h></code> would cause an infinite recursion of including if using <code>#include</code>, as it would re-include itself. <code>#include_next</code> solves this by including the next <code><stdio.h></code> found. <syntaxhighlight lang="c"> // override_stdio/stdio.h #ifndef MY_STDIO_H #define MY_STDIO_H
// Custom overrides #define printf(...) my_custom_printf(__VA_ARGS__)
// Include the next stdio.h in the search path #include_next <stdio.h> #endif </syntaxhighlight>
=== <code>#import</code> === Unlike C and C++, Objective-C includes an <code>#import</code> directive that is like <code>#include</code> but results in a file being included only once {{endash}} eliminating the need for include guards and <code>#pragma once</code>. It is a standard part of Objective-C.
<syntaxhighlight lang="objective-c"> #import <Foundation/Foundation.h> #import "MyClass.h" </syntaxhighlight>
In Microsoft Visual C++ (MSVC), there also exists an <code>#import</code> preprocessor directive, used to import type libraries.<ref>{{Cite web|title=#import directive (C++)|url=https://learn.microsoft.com/en-us/cpp/preprocessor/hash-import-directive-cpp|publisher=learn.microsoft.com}}</ref> It is a nonstandard directive.
<syntaxhighlight lang="cpp"> #import "C:\\Program Files\\Common Files\\System\\ado\\msado15.dll" no_namespace rename("EOF", "ADOEOF") </syntaxhighlight>
These should not be confused with the C++ keyword <code>import</code>, which is used to import C++ modules (since C++20), and is not a preprocessor directive.
=== Null directive === The null directive, which consists only of the <code>#</code> character, alone on a single line, is a non-standard directive in Microsoft Visual C++. It has no effect.<ref>{{Cite web|title=Null directive|url=https://learn.microsoft.com/en-us/cpp/preprocessor/null-directive|publisher=learn.microsoft.com}}</ref>
=== <code>#nullable</code> === The <code>#nullable</code> directive in C# is used to enable and disable nullable reference types. To enable them, use <code>#nullable enable</code>, and <code>#nullable disable</code> to disable them.
<syntaxhighlight lang="csharp"> #nullable enable
string? name = null; // OK string fullName = null; // Warning: possible null assignment
#nullable disable
string test = null; // No warning </syntaxhighlight>
This directive does not exist in C/C++.
=== <code>#region</code> === The <code>#region</code> and <code>#endregion</code> directives in C# are used to expand/collapse sections of code in IDEs, and has no effect on actual compilation of the program. It is primarily used for code organisation and readability. <syntaxhighlight lang="csharp"> #region Helper methods
void Log(string message) { Console.WriteLine(message); }
#endregion </syntaxhighlight>
While this directive does not exist in C/C++, MSVC and Visual Studio instead have <code>#pragma region</code> and <code>#pragma endregion</code>.<ref>{{Cite web|url= https://learn.microsoft.com/en-us/cpp/preprocessor/region-endregion|title = region and endregion pragma}}</ref> Thus the equivalent C++ code would be:
<syntaxhighlight lang="c++"> using std::string_view;
#pragma region Helper methods
void log(string_view message) { std::println(message); }
#pragma endregion </syntaxhighlight>
=== <code>#using</code> === C++/CLI has the <code>#using</code> directive, which is used to import metadata into a program from a Microsoft Intermediate Language file (such as a {{mono|.dll}} file).<ref>{{Cite web|title=#using directive (C++/CLI)|url=https://learn.microsoft.com/en-us/cpp/preprocessor/hash-using-directive-cpp|publisher=learn.microsoft.com|date=29 June 2022}}</ref>
<syntaxhighlight lang="c++"> #using <MyComponent.dll> #using "AssemblyA.dll" #using "AssemblyB.dll"
using namespace System;
public ref class B { public void Test(A a) { // ... } };
int main(array<String^>^ args) { A a; B b; B.Test(a); } </syntaxhighlight>
== Other uses == Traditionally, the C preprocessor was a separate development tool from the compiler with which it is usually used. In that case, it can be used separately from the compiler. Notable examples include use with the (deprecated) imake system and for preprocessing Fortran. However, use as a general purpose preprocessor is limited since the source code language must be relatively C-like for the preprocessor to parse it.<ref name="gnu-cpp-overview"/>
The GNU Fortran compiler runs "traditional mode" CPP before compiling Fortran code if certain file extensions are used.<ref>{{cite web|title=1.3 Preprocessing and conditional compilation|url=https://gcc.gnu.org/onlinedocs/gfortran/Preprocessing-and-conditional-compilation.html|publisher=GNU Project}}</ref> Intel offers a Fortran preprocessor, fpp, for use with the ifort compiler, which has similar capabilities.<ref>{{cite web|title=Using the fpp Preprocessor|url=https://software.intel.com/en-us/node/524749|publisher=Intel|access-date=14 October 2015}}</ref>
CPP also works acceptably with most assembly languages and Algol-like languages. This requires that the language syntax not conflict with CPP syntax, which means no lines starting with <code>#</code> and that double quotes, which CPP interprets as string literals and thus ignores, don't have syntactical meaning other than that. The "traditional mode" (acting like a pre-ISO C preprocessor) is generally more permissive and better suited for such use.<ref>{{cite web |title=Overview (The C Preprocessor) |url=https://gcc.gnu.org/onlinedocs/cpp/Overview.html |website=gcc.gnu.org |quote=Having said that, you can often get away with using cpp on things which are not C. Other Algol-ish programming languages are often safe (Ada, etc.) So is assembly, with caution. -traditional-cpp mode preserves more white space, and is otherwise more permissive. Many of the problems can be avoided by writing C or C++ style comments instead of native language comments, and keeping macros simple.}}</ref>
Some modern compilers such as the GNU C Compiler provide preprocessing as a feature of the compiler; not as a separate tool.
==Limitations== === Text substitution limitations === Text substitution has a relatively high risk of causing a software bug as compared to other programming constructs.<ref>{{cite web |title = The power of ten - Rules for developing safety critical code |url = http://spinroot.com/gerard/pdf/P10.pdf |author = Gerard J. Holzmann |page = 4 |work = safety of macros }}</ref><ref name="processor"> {{cite journal |author1=Michael D. Ernst |author2=Greg J. Badros |author3=David Notkin |title=An empirical analysis of c preprocessor use |journal=IEEE Transactions on Software Engineering |url = http://dl.acm.org/citation.cfm?id=631305 |date = December 2002 |volume=28 |issue=12 |pages=1146–1170 |doi=10.1109/TSE.2002.1158288 |bibcode=2002ITSEn..28.1146E |url-access=subscription }}</ref>
In particular, C preprocessor macros lack syntactic awareness and fail to preserve lexical structure, unlike syntactic macros seen in Lisp-like languages, Scala<ref>{{Cite web|title=Def Macros|url=https://docs.scala-lang.org/overviews/macros/overview.html|access-date=2021-04-05|website=Scala Documentation}}</ref>, or Rust<ref>{{Cite web|title=Macros - The Rust Programming Language|url=https://doc.rust-lang.org/book/ch19-06-macros.html|access-date=2021-04-05|website=doc.rust-lang.org}}</ref>.
====Hidden multiple evaluation==== Consider the common definition of a <code>MAX</code> macro:
<syntaxhighlight lang=C> #define MAX(a, b) (((a) > (b)) ? (a) : (b)) </syntaxhighlight>
The expressions represented by <code>a</code> and <code>b</code> are both evaluated two times due to macro expansion, but this aspect is not obvious in the code where the macro is referenced. If the actual expressions have constant value, then multiple evaluation is not problematic from a logic standpoint even though it can affect runtime performance. But if an expression evaluates to a different value on subsequent evaluation, then the result may be unexpected. For example, given <code>int i = 1, j = 2;</code>, the result of <code>MAX(i, j)</code> is 2. If <code>a</code> and <code>b</code> were only evaluated once, the result of <code>MAX(i++, j++)</code> would be the same, but with double evaluation the result is 3.
====Hidden order of operation==== Failure to bracket arguments can lead to unexpected results. For example, a macro to double a value might be written as:
<syntaxhighlight lang=C> #define DOUBLE(x) 2 * x </syntaxhighlight>
But <code>DOUBLE(1 + 2)</code> expands to <code>2 * 1 + 2</code>, which due to order of operations evaluates to 4 when the expected is 6. To mitigate this problem, a macro should bracket all expressions and substitution variables:
<syntaxhighlight lang=C> #define DOUBLE(x) (2 * (x)) </syntaxhighlight>
===Not general purpose=== The C preprocessor is not Turing-complete, but comes close. Recursive computations can be specified, but with a fixed upper bound on the amount of recursion performed.<ref>{{cite web |url=https://stackoverflow.com/a/10526117 |title=Is the C99 preprocessor Turing complete? |url-status=live |archive-url=https://web.archive.org/web/20160424212425/https://stackoverflow.com/questions/3136686/is-the-c99-preprocessor-turing-complete/10526117 |archive-date=2016-04-24}}</ref> However, the C preprocessor is not designed to be, nor does it perform well as, a general-purpose programming language. As the C preprocessor does not have features of some other preprocessors, such as recursive macros, selective expansion according to quoting, and string evaluation in conditionals, it is very limited in comparison to a more general macro processor such as m4.
==Phase out== Due to its limitations and lack of type safety (as the preprocessor is completely oblivious to C/C++ grammar, performing only text substitutions), C and C++ language features have been added over the years to minimize the value and need for the preprocessor.
===Constant=== For a long time, a preprocessor macro provided the preferred way to define a constant value. An alternative has always been to define a <code>const</code> variable, but that results in consuming runtime memory. A newer language construct (since C++11 and C23), <code>constexpr</code> allows for declaring a compile-time constant value that need not consume runtime memory.<ref>{{cite web |author1=Gabriel Dos Reis |author2=Bjarne Stroustrup |date=22 March 2010 |title=General Constant Expressions for System Programming Languages, Proceedings SAC '10 |url=http://www.stroustrup.com/sac10-constexpr.pdf |url-status=live |archive-url=https://web.archive.org/web/20180613125602/http://www.stroustrup.com/sac10-constexpr.pdf |archive-date=13 June 2018 |access-date=8 July 2024}}</ref>
===Inline function=== For a long time, a function-like macro was the only way to define function-like behavior that did not incur runtime function call overhead. Via the <code>inline</code> keyword and optimizing compilers that inline automatically, some functions can be invoked without call overhead.
===Import=== The include directive limits code structure since it only allows including the content of one file into another. More modern languages support a module concept that has public symbols that other modules import {{endash}} instead of including file content. Many contend that resulting code has reduced boilerplate and is easier to maintain since there is only one file for a module, not both a header and a body. C++20 adds modules, and an <code>import</code> statement that is not handled via preprocessing.<ref>{{cite web|url=https://isocpp.org/files/papers/n4720.pdf|title=N4720: Working Draft, Extensions to C++ for Modules|archive-date=2019-04-30|archive-url=https://web.archive.org/web/20190430095053/https://isocpp.org/files/papers/n4720.pdf|url-status=live}}</ref><ref>{{cite web|url=https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1857r1.html|title=P1857R1 – Modules Dependency Discovery}} </ref> Modules in C++ compile faster and link faster than traditional headers,<ref>{{cite web|url=https://learn.microsoft.com/en-us/cpp/build/compare-inclusion-methods?view=msvc-170|title=Overview of modules in C++|date=12 February 2022 |publisher=Microsoft}}</ref> and eliminate the necessity of {{mono|#include}} guards or {{mono|#pragma once}}. Until C++26, <code>import</code>, <code>export</code>, and <code>module</code> keywords were partially handled by the preprocessor.
For code bases that cannot migrate to modules immediately, C++ also offers "header units" as a feature, which allows header files to be imported in the same way a module would. Unlike modules, header units may emit macros, offering minimal breakage between migration. Header units are designed to be a transitional solution before totally migrating to modules.<ref>{{cite web|url=https://learn.microsoft.com/en-us/cpp/build/walkthrough-header-units?view=msvc-170|title=Walkthrough: Build and import header units in Microsoft Visual C++|date=12 April 2022 |publisher=Microsoft}}</ref> For instance, one may write <syntaxhighlight lang="C++" inline>import <string>;</syntaxhighlight> instead of <syntaxhighlight lang="C++" inline>#include <string></syntaxhighlight>, or <syntaxhighlight lang="C++" inline>import "MyHeader.hpp";</syntaxhighlight> instead of <syntaxhighlight lang="C++" inline>#include "MyHeader.hpp"</syntaxhighlight>. Paradoxically, most build systems, such as CMake, do not currently support this feature.
In Clang, a non-standard module feature for C is offered, allowing importing headers as modules.<ref name="clangcmodules">{{Cite web|url=https://clang.llvm.org/docs/Modules.html|title=Modules|website=clang.llvm.org}}</ref>
== See also == * C syntax * C++ syntax * C# syntax * Make * m4 (computer language) * PL/I preprocessor
== References == {{reflist}}
==Sources== * {{cite journal |last1=Ritchie |first1=Dennis M. |author-link=Dennis Ritchie |date=March 1993 |title=The Development of the C Language |journal=ACM SIGPLAN Notices |volume=28 |issue=3 |pages=201–208 |doi=10.1145/155360.155580 |publisher=ACM|doi-access=free }} * {{cite conference |ref=none |last1=Ritchie |first1=Dennis M. |year=1993 |title=The Development of the C Language |pages=201–208 |doi=10.1145/154766.155580 |url=http://www.bell-labs.com/usr/dmr/www/chist.html |book-title=The Second ACM SIGPLAN Conference on History of Programming Languages (HOPL-II) |publisher=ACM|isbn=0-89791-570-4 |access-date=4 November 2014|url-access=subscription }}
== External links == {{Wikibooks|C Programming/Preprocessor}} * [http://www.open-std.org/JTC1/SC22/WG14/www/standards ISO/IEC 9899]. The latest publicly available version of the C11 standard is [https://www.open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf the final draft]. * [https://gcc.gnu.org/onlinedocs/cpp/index.html GNU CPP online manual] * [http://msdn.microsoft.com/en-us/library/y4skk93w(VS.80).aspx Visual Studio .NET preprocessor reference] * [https://predef.sourceforge.net/ Pre-defined C/C++ Compiler Macros project]: lists "various pre-defined compiler macros that can be used to identify standards, compilers, operating systems, hardware architectures, and even basic run-time libraries at compile-time"
{{CProLang}} {{C++ programming language}}
Category:C (programming language) Category:Transformation languages Category:Macro programming languages