Content deleted Content added
(45 intermediate revisions by 19 users not shown) | |||
Line 14:
}}</ref>
The [[C Sharp (programming language)|C#]] programming language also allows for directives,
The [[Haskell]] programming language also allows the usage of the C preprocessor
Features of the preprocessor are encoded in [[source code]] as [[Directive (programming)|directives]] that start with <code>#</code>.
Line 23:
== 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.
Line 42 ⟶ 43:
* <code>#warning</code>
* <code>#pragma</code>
* <code>defined</code> (follows a conditional directive; not actually a directive, but rather an operator)
* <code>
* <code>
* <code>
* <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# ===
Line 67 ⟶ 71:
* <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 ===
Line 89 ⟶ 95:
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 [[C trigraph|trigraph sequences]] with the characters they represent. This phase
# Line splicing: Physical source lines that are continued with [[escape character|escaped]] [[newline]] sequences are ''spliced'' to form logical lines.
# Tokenization: The preprocessor breaks the result into ''preprocessing tokens'' and [[Whitespace character|whitespace]]. It replaces comments with whitespace.
Line 102 ⟶ 108:
=== 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 (computer programming)|function]] <code>printf()</code> and other symbols are declared.
<syntaxhighlight lang="cpp">
#include <stdio.h>
int main(void) {
printf("Hello, World!\n");
Line 116 ⟶ 128:
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
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|
==== 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 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 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 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 */
const signed char alignedDataString[] __attribute__ ((aligned (8))) = {
#embed "attributes.xml"
};
int main() {
return
#embed </dev/urandom> limit(1)
;
}
</syntaxhighlight>
=== Conditional compilation ===
Line 216 ⟶ 256:
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 [
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>.
Line 238 ⟶ 278:
</syntaxhighlight>
===
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:
Line 259 ⟶ 314:
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:
Line 277 ⟶ 332:
</syntaxhighlight>
===
As of [[C23 (C standard revision)|C23]]
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 [[pragma once|{{mono|#pragma once}}]], which behaves the same way an [[include guard|{{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 (computing)|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>
=== <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 [[pragma once|<code>#pragma once</code>]].
<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>
The Objective-C directive should not be confused with the C++ keyword <code>import</code>, which is used to import C++ [[Modules (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++">
#pragma region Helper methods
void log(std::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 ==
Line 339 ⟶ 463:
|page = 4
|work = safety of macros
}}</ref><ref name="processor">
{{cite journal |author1=Michael D. Ernst |author2=[[Greg J. Badros]] |author3=David Notkin
|
|date = December 2002
|volume=28 |issue=12 |pages=1146–1170 |doi=10.1109/TSE.2002.1158288 |bibcode=2002ITSEn..28.1146E |url-access=subscription }}</ref>
;Hidden multiple evaluation
Line 384 ⟶ 508:
;Import
The include directive limits code structure since it only allows including the content of one file into another. More modern languages support a [[modular programming|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 [[
</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 [[include guard|{{mono|#include}} guards]] or [[pragma once|{{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.
== See also ==
Line 400 ⟶ 526:
==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=[[Association for Computing Machinery|ACM]]|isbn=0-89791-570-4 |access-date=4 November 2014|url-access=subscription }}
== External links ==
Line 407 ⟶ 533:
* [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]
* [
{{CProLang}}
|