Content deleted Content added
→Binary resource inclusion: Added the C++ paper as a source as well |
|||
(19 intermediate revisions by 7 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 44:
* <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 94 ⟶ 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 ==
Line 132 ⟶ 133:
==== 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
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]].
Line 139:
<syntaxhighlight lang="cpp">
const unsigned char
#embed "art.png"
};
/* specify any type which can be initialized form integer constant expressions will do */
const char
#embed "data.bin"
};
/* attributes work just as well */
const signed char
#embed "attributes.xml"
};
Line 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 346:
==Non-standard features ==
===
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.
Line 359:
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>
===
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>
===
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>]].
Line 370:
</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|
<syntaxhighlight lang="cpp">
Line 376:
</syntaxhighlight>
The Objective-C directive should not be confused with the C++ keyword <code>import</code>, which is used to import C++ [[
===
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.
Line 394 ⟶ 397:
This directive does not exist in C/C++.
===
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">
Line 412 ⟶ 415:
#pragma region Helper methods
void log(
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>
Line 442 ⟶ 468:
|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>
;Hidden multiple evaluation
Line 482 ⟶ 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.
Line 507 ⟶ 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}}
|