Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
C preprocessor
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== 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 'stdio.h' in which the [[Function (computer programming)|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 [[software build|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 [[include guard|{{mono|#include}} guard]] or if supported by the preprocessor [[pragma once|{{mono|#pragma once}}]] to prevent multiple inclusion. ==== Binary resource inclusion ==== [[C23 (C standard revision)|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 though it's 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> 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 literal]]s 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>[[Limits.h|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 [[angle brackets|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 [[C++11#Attributes|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 icon_display_data[] = { #embed "art.png" }; /* specify any type which can be initialized form integer constant expressions will do */ const char reset_blob[] = { #embed "data.bin" }; /* attributes work just as well */ const signed char aligned_data_str[] __attribute__ ((aligned (8))) = { #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 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"> #undef VALUE </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 [[ANSI C#C89 and C90|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 [[wikt: agnostic|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 Macro|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 [http://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> #elif defined _WIN32 /* _WIN32 is usually defined by compilers targeting 32 or 64 bit Windows systems */ # include <windows.h> #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. ===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 == 10 // if X equals 10, the preprocessor sees #if 10 == 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 "foo" and <code>xstr(foo)</code> expands to "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 definition: <syntaxhighlight lang="cpp"> #define DECLARE_STRUCT_TYPE(name) typedef struct name##_s name##_t </syntaxhighlight> <code>DECLARE_STRUCT_TYPE(g_object)</code> expands to <code>typedef struct g_object_s g_object_t</code>. === 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 (C standard revision)|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>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)