中药饮片是什么| 芍药什么时候开花| 印度为什么没把墨脱占领| 1992年属猴的是什么命| 小孩咬手指甲是什么原因| 郑恺的父母是做什么的| 艾滋病是什么样的| 吃了避孕药后几天出血是什么原因| 原子序数等于什么| 女性尿酸高有什么症状表现| 避孕套和安全套有什么区别| 禅让制是什么意思| 山药与什么食物相克| 为什么会甲亢| 类风湿是什么原因引起的| afp是什么传染病| 耳朵痛用什么药| vdo是什么牌子| 孕妇为什么不能参加婚礼| 争奇斗艳的斗是什么意思| 妇科支原体是什么病| 黄瓜什么时候种| 孕妇生气对胎儿有什么影响| 稽留流产是什么意思| 智齿什么时候拔最好| 鸡婆是什么意思| 咽喉异物感吃什么药| 肾结石吃什么药能化石| 第一次查怀孕挂什么科| 胸口疼挂什么科| 九斗一簸箕有什么说法| 荷花是什么季节开放的| 小孩上火吃什么药| 兰花什么时候开花| 教皇是什么意思| tia是什么| 什么的梅花| 作是什么意思| 高血压二级是什么意思| 80年属什么的| 2021属什么生肖| 沐猴而冠代表什么生肖| 鹰嘴桃什么时候成熟| a型血可以接受什么血型| 11月10号是什么星座| 多喝柠檬水有什么好处| 不安分是什么意思| 基因突变是什么病| 深覆合是什么样子的| 反应是什么意思| 曹操的脸谱是什么颜色| 维生素b有什么功效| 天长地久是什么意思| 女性尿频吃什么药| 87年什么命| library是什么意思| 外阴瘙痒用什么药膏| 梦见砍竹子是什么意思| 吃什么食物能长高| 我国最早的中医学专著是什么| 政协主席是什么级别| 桦树茸什么功效| 怀孕一个月有什么反应| 谦虚的近义词是什么| adh医学上是什么意思| 四次元是什么意思啊| 什么叫窦性心律不齐| 盐水洗脸有什么好处| 英国为什么叫日不落帝国| 可乐加味精女人喝了什么效果| 头顶不舒服是什么原因| 梦见洗头是什么预兆| 苹果枸杞红枣煮水喝有什么功效| 饣与什么有关| 什么网站可以看三节片| 八字不合是什么生肖| 礼部尚书是什么官| 正月初十是什么星座| 整夜做梦是什么原因| 不遗余力的遗是什么意思| 在什么地方| 长宽高用什么字母表示| 颈椎骨质增生吃什么药效果好| 心超是检查什么的| 幽冥是什么意思| ac疫苗是预防什么的| 为什么一吃完饭就肚子疼| 拉肚子吃什么药好得快| 胃胀气打嗝吃什么药| 取保候审需要什么条件| 眼角下面长斑是什么原因引起的| 包皮是什么样子的| 口腔溃疡是缺什么| 金贵肾气丸治什么病| 和谐的什么| 硝石是什么| 肚子硬是什么原因| 很能睡觉是什么原因| 起床头疼是什么原因| 液蜡是什么| 鲁冰花是什么花| 1964年什么命| 女人梦到被蛇咬是什么意思| 闭口是什么样子图片| 喜欢一个人会有什么表现| 梭是什么意思| 鼻腔有臭味是什么原因| 消化不好吃什么药最好| 安道尔微信暗示什么| 经常吃维生素c有什么好处和坏处| 哺乳期什么东西不能吃| 择日不如撞日什么意思| 血钾是什么意思| 支气管炎吃什么药最好| 急性子是什么意思| 慢性非萎缩性胃炎是什么意思| 温度计代表什么生肖| 绝对值什么意思| 瘪嘴是什么意思| 发烧吃什么水果| 生酮饮食是什么| 早搏有什么危害| 精神焦虑症有什么表现有哪些| 山竹里面黄黄的是什么可以吃吗| 梦见摘黄瓜是什么意思| 绝无仅有的绝什么意思| 肌酐500多属于什么期怎么治疗| 安全期什么时候| 五鬼是什么意思| 铁补多了有什么副作用| 牙龈肿大是什么原因| 脖子为什么会痒| 上火吃什么药最有效果| 草鱼吃什么| 商品下架是什么意思| 六味地黄丸什么人不能吃| 巨蟹座是什么星象| 拜阿司匹灵是什么药| 中山大学是什么级别| 2020年是什么生肖| 生粉和淀粉有什么区别| 带节奏是什么意思| 男性下焦湿热吃什么药| 熟地有什么功效| 党员有什么好处| 故友是什么意思| 益生菌对人体有什么好处| 锋字五行属什么| 东北和山东有什么区别| only是什么牌子| 讹诈是什么意思| 痱子涂什么药膏好| 香草味是什么味道| 低血压有什么症状| 氟哌酸是什么药| 异常白细胞形态检查是查什么病| 朋友妻不可欺是什么意思| 什么样的树| 洗漱是什么意思| 寒湿重吃什么中成药| 你问我爱你有多深是什么歌| 珍珠纱是什么面料| 历史是个什么玩意儿| 喉咙痒吃什么药好| 嘴唇发麻是什么原因| 怀孕吃核桃对宝宝有什么好处| 耳麦是什么| 6月29日什么星座| 天涯海角是什么生肖| 5.5号是什么星座| 中国第一大姓是什么| 茶艺师是做什么的| 0z是什么单位| 烤冷面的面皮是什么面| 什么叫化学性肝损伤| 猪脚和猪蹄有什么区别| 彩礼是什么意思| 安吉白茶属于什么茶类| 20年是什么婚姻| 撤退性出血是什么| 什么是幸福| 狗摇尾巴是什么意思| 龋齿什么意思| 循证是什么意思| 怀孕了吃什么药能打掉| 曼波是什么意思| 肾积水吃什么药最好| 梦见刺猬是什么意思| 跨宽穿什么裤子好看| 甲钴胺不能和什么药一起服用| 诡辩是什么意思| 坐落是什么意思| ad医学上是什么意思| 11月份是什么季节| 粘米粉是什么粉| 尿道炎挂什么科| 学英语先从什么学起| 电销是什么工作| 宫腔粘连带是什么意思| 脂肪瘤是什么原因引起的| 做梦梦到地震预示着什么| 未曾谋面什么意思| 吴京为什么看上谢楠| 月亮杯是什么东西| 风湿和类风湿有什么区别| 高血压一级是什么意思| 中性粒细胞绝对值偏高是什么原因| 喆读什么| 哭什么| dpl是什么意思| 梦到熊是什么意思| 胸膜牵拉是什么意思| friend什么意思中文| 冠心病是什么病| q波异常是什么意思| 维生素b2治什么病| 陶渊明是什么派诗人| 桂林有什么好玩的景点| 微盟是做什么的| 英气是什么意思| 玫瑰什么时候开花| 电风扇什么牌子好| 牙齿松动吃什么药最好| 羊宝是什么| 千千阙歌什么意思| 薄荷有什么功效和作用| 乌唇是什么原因| 辐射对称是什么意思| 霉菌是什么| 克卜勒是什么意思| 晚上尿多是什么病| 潮喷是什么感觉| bug是什么意思中文翻译| grace什么意思| 情感是什么意思| 赛能是什么药| 磨砂膏有什么作用| 腰果不能和什么一起吃| 梦见游泳是什么预兆| 吃西红柿有什么好处| 嘉靖为什么不杀海瑞| 木字旁与什么有关| 梦见买帽子是什么意思| 形同陌路什么意思| 反式脂肪酸是什么意思| 壬午日五行属什么| amo是什么意思| 2.13是什么星座| 月经不来又没怀孕是什么原因| 女人脚肿是什么原因| 圆脸适合什么发型男| 鱼油有什么用| 跌打损伤挂什么科| 曲马多是什么| 多字五行属什么| 支抗钉是什么| CA是什么激素| 过氧化氢是什么意思| 睾丸为什么会痛| 上海市委书记什么级别| 玩票是什么意思| 藏红花可以搭配什么泡水喝| 情商什么意思| 丹参有什么作用和功效| 百度

金正恩向阿萨德致贺电:继续声援叙利亚正义伟业

百度 为贯彻落实《证券交易所管理办法》要求,完善自律管理程序和标准,保护自律管理对象合法权益,上交所对2013年《纪律处分和监管措施实施办法》进行修订,同时制定《自律管理听证实施细则》,于23日发布实施。

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 and is used to process other kinds of files.[1]

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.[2]

The C# programming language also allows for directives, even though they cannot be used for creating macros, and is generally more intended for features such as conditional compilation.[3] 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").

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

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

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

Preprocessor directives

edit

The following languages have the following accepted directives.

C/C++

edit

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

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

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

Haskell also accepts C preprocessor directives.

Although C# does not have a separate preprocessor, these directives are processed as if there were one.

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

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

Objective-C

edit

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

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

History

edit

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

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.[5]

Phases

edit

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

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

Features

edit

File inclusion

edit

There are two directives in the C preprocessor for including contents of files:

  • #include, used for directly including the contents of a file in-place (typically containing code of some kind)
  • #embed, used for directly including or embedding the contents of a binary resource in-place

Code inclusion

edit

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

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

#include <stdio.h>

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

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

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

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

Binary resource inclusion

edit

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

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

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)
    ;
}

Conditional compilation

edit

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

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

The following demonstrates more complex logic:

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

Macro string replacement

edit
Object-like

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

#define VALUE 1 / 12
Function-like

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

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

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

Expansion

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

Variadic

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

Order of expansion

Function-like macro expansion occurs in the following stages:

  1. Stringification operations are replaced with the textual representation of their argument's replacement list (without performing expansion).
  2. Parameters are replaced with their replacement list (without performing expansion).
  3. Concatenation operations are replaced with the concatenated result of the two operands (without expanding the resulting token).
  4. Tokens originating from parameters are expanded.
  5. The resulting tokens are expanded as normal.

This may produce surprising results:

#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)

Undefine macro

edit

A macro definition can be removed from the preprocessor context via #undef such that subsequent reference to the macro token will not expand. For example:

#undef VALUE

Predefined macros

edit

The preprocessor provides some macro definitions automatically. The C standard specifies that __FILE__ expands to the name of the file being processed and __LINE__ expands to the number of the line that contains the directive. The following macro, DEBUGPRINT, formats and prints a message with the file name and line number.

#define DEBUGPRINT(_fmt, ...) printf("[%s:%d]: " _fmt, __FILE__, __LINE__, __VA_ARGS__)

For the example code below that is on line 30 of file util.c and for count 123, the output is: [util.c:30]: count=123.

DEBUGPRINT("count=%d\n", count);

The first C Standard specified that __STDC__ expand to "1" if the implementation conforms to the ISO standard and "0" otherwise and that __STDC_VERSION__ expand to a numeric literal specifying the version of the standard supported by the implementation. Standard C++ compilers support the __cplusplus macro. Compilers running in non-standard mode must not set these macros or must define others to signal the differences.

Other standard macros include __DATE__, the current date, and __TIME__, the current time.

The second edition of the C Standard, C99, added support for __func__, 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.[8][9][10] An X-Macro is a header file. Commonly, these use the extension .def instead of the traditional .h . 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 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 _WIN32.[11] This allows code, including preprocessor commands, to compile only when targeting Windows systems. A few compilers define WIN32 instead. For such compilers that do not implicitly define the _WIN32 macro, it can be specified on the compiler's command line, using -D_WIN32.

#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

The example code tests if a macro __unix__ is defined. If it is, the file <unistd.h> is then included. Otherwise, it tests if a macro _WIN32 is defined instead. If it is, the file <windows.h> is then included.

Line control

edit

The values of the predefined macros __FILE__ and __LINE__ can be set for a subsequent line via the #line directive. In the code below, __LINE__ expands to 314 and __FILE__ to "pi.c".

#line 314 "pi.c"
printf("line=%d file=%s\n", __LINE__, __FILE__);

Operators

edit

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 defined operator, and the # stringificafion operator. This allows the preprocessor to make evaluations such as:

#if X == 10 // if X equals 10, the preprocessor sees #if 10 == 10

Defined operator

edit

While the defined operator, denoted by defined 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 defined operator.

#if defined(MY_MACRO)
#if defined MY_MACRO

Token stringification operator

edit

The stringification operator (a.k.a. stringizing operator), denoted by # converts a token into a string literal, escaping any quotes or backslashes as needed. For definition:

#define str(s) #s

str(\n) expands to "\n" and str(p = "foo\n";) expands to "p = \"foo\\n\";".

If stringification of the expansion of a macro argument is desired, two levels of macros must be used. For definition:

#define xstr(s) str(s)
#define str(s) #s
#define foo 4

str(foo) expands to "foo" and xstr(foo) 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

edit

The token pasting operator, denoted by ##, concatenates two tokens into one. For definition:

#define DECLARE_STRUCT_TYPE(name) typedef struct name##_s name##_t

DECLARE_STRUCT_TYPE(g_object) expands to typedef struct g_object_s g_object_t.

Abort

edit

Processing can be aborted via the #error directive. For example:

#if RUBY_VERSION == 190
#error Ruby version 1.9.0 is not supported
#endif

Warning

edit

As of C23[12] and C++23,[13] a warning directive, #warning, 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:

// 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.")

Non-standard features

edit

Pragma

edit

The #pragma 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 #pragma STDC ..., which are used to control the floating-point implementation. The alternative, macro-like form _Pragma(...) was also added.

One of the most popular uses of the #pragma directive is #pragma once, which behaves the same way an #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

edit

Many implementations do not support trigraphs or do not replace them by default.

Assertion

edit

Some Unix preprocessors provided an assertion feature – which has little similarity to standard library assertions.[14]

Include next

edit

GCC provides #include_next for chaining headers of the same name.[15]

Import

edit

Unlike C and C++, Objective-C includes an #import directive that is like #include but results in a file being included only once – eliminating the need for include guards and #pragma once.

#import <Foundation/Foundation.h>
#import "MyClass.h"

In Microsoft Visual C++ (MSVC), there also exists an #import preprocessor directive, used to import type libraries.[16] It is a nonstandard directive.

#import "C:\\Program Files\\Common Files\\System\\ado\\msado15.dll" no_namespace rename("EOF", "ADOEOF")

The Objective-C directive should not be confused with the C++ keyword import, which is used to import C++ modules (since C++20), and is not a preprocessor directive.

Nullable

edit

The #nullable directive in C# is used to enable and disable nullable reference types. To enable them, use #nullable enable, and #nullable disable to disable them.

#nullable enable

string? name = null; // OK
string fullName = null; // Warning: possible null assignment

#nullable disable

string test = null; // No warning

This directive does not exist in C/C++.

Region

edit

The #region and #endregion 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.

#region Helper methods

void Log(string message)
{
    Console.WriteLine(message);
}

#endregion

While this directive does not exist in C/C++, MSVC and Visual Studio instead have #pragma region and #pragma endregion.[17] Thus the equivalent C++ code would be:

#pragma region Helper methods

void log(const std::string& message) {
    std::println(message);
}

#pragma endregion

Other uses

edit

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.[2]

The GNU Fortran compiler runs "traditional mode" CPP before compiling Fortran code if certain file extensions are used.[18] Intel offers a Fortran preprocessor, fpp, for use with the ifort compiler, which has similar capabilities.[19]

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 # 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.[20]

Some modern compilers such as the GNU C Compiler provide preprocessing as a feature of the compiler; not as a separate tool.

Limitations

edit

Text substitution limitations

edit

Text substitution has a relatively high risk of causing a software bug as compared to other programming constructs.[21][22]

Hidden multiple evaluation

Consider the common definition of a max macro:

#define max(a,b) (((a) > (b)) ? (a) : (b))

The expressions represented by a and b 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 int i = 1; j = 2;, the result of max(i,j) is 2. If a and b were only evaluated once, the result of max(i++,j++) 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:

#define double(x) 2 * x

But double(1 + 2) expands to 2 * 1 + 2 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:

#define double(x) (2 * (x))

Not general purpose

edit

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.[23] 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

edit

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 const variable, but that results in consuming runtime memory. A newer language construct (since C++11 and C23), constexpr allows for declaring a compile-time constant value that need not consume runtime memory.[24]

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 inline 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 – 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 import statement that is not handled via preprocessing.[25][26] Modules in C++ compile faster and link faster than traditional headers,[27] and eliminate the necessity of #include guards or #pragma once. Until C++26, import, export, and module 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.[28] For instance, one may write import <string>; instead of #include <string>, or import "MyHeader.hpp"; instead of #include "MyHeader.hpp". Paradoxically, most build systems, such as CMake, do not currently support this feature.

See also

edit

References

edit
  1. ^ General-purpose text preprocessing with the C preprocessor. Featuring JavaScript
  2. ^ a b "The C Preprocessor: Overview". Retrieved 17 July 2016.
  3. ^ "C# preprocessor directives". Microsoft. 14 January 2022.
  4. ^ Ritchie (1993)
  5. ^ "Bell SAP – SAP with conditional and recursive macros". HOPL: Online Historical Encyclopaedia of Programming Languages. Archived from the original on 14 October 2023. Retrieved 4 October 2020.
  6. ^ "WG14-N3017 : #embed – a scannable, tooling-friendly binary resource inclusion mechanism". open-std.org. 27 June 2022. Archived from the original on 24 December 2022.
  7. ^ "#embed - a scannable, tooling-friendly binary resource inclusion mechanism". open-std.org.
  8. ^ Wirzenius, Lars. C "Preprocessor Trick For Implementing Similar Data Types". Retrieved January 9, 2011
  9. ^ Meyers, Randy (May 2001). "The New C: X Macros". Dr. Dobb's Journal. Retrieved 1 May 2008.
  10. ^ Beal, Stephan (August 2004). "Supermacros". Retrieved 27 October 2008. {{cite journal}}: Cite journal requires |journal= (help)
  11. ^ List of predefined ANSI C and Microsoft C++ implementation macros.
  12. ^ "WG14-N3096 : Draft for ISO/IEC 9899:2023" (PDF). open-std.org. 1 April 2023. Archived (PDF) from the original on 2 April 2023.
  13. ^ "Working Draft, Standard for Programming Language C++" (PDF). 22 March 2023.
  14. ^ GCC Obsolete features
  15. ^ "Wrapper Headers (The C Preprocessor)".
  16. ^ "#import directive (C++)".
  17. ^ "region and endregion pragma".
  18. ^ "1.3 Preprocessing and conditional compilation". GNU Project.
  19. ^ "Using the fpp Preprocessor". Intel. Retrieved 14 October 2015.
  20. ^ "Overview (The C Preprocessor)". gcc.gnu.org. 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.
  21. ^ Gerard J. Holzmann. "The power of ten - Rules for developing safety critical code" (PDF). safety of macros. p. 4.
  22. ^ Michael D. Ernst; Greg J. Badros; David Notkin (December 2002). "An empirical analysis of c preprocessor use". IEEE Transactions on Software Engineering. 28 (12): 1146–1170. doi:10.1109/TSE.2002.1158288.
  23. ^ "Is the C99 preprocessor Turing complete?". Archived from the original on 24 April 2016.
  24. ^ Gabriel Dos Reis; Bjarne Stroustrup (22 March 2010). "General Constant Expressions for System Programming Languages, Proceedings SAC '10" (PDF). Archived (PDF) from the original on 13 June 2018. Retrieved 8 July 2024.
  25. ^ "N4720: Working Draft, Extensions to C++ for Modules" (PDF). Archived (PDF) from the original on 30 April 2019.
  26. ^ "P1857R1 – Modules Dependency Discovery".
  27. ^ "Overview of modules in C++". Microsoft. 12 February 2022.
  28. ^ "Walkthrough: Build and import header units in Microsoft Visual C++". Microsoft. 12 April 2022.

Sources

edit
edit
苦海翻起爱恨是什么歌 卜卜脆是什么意思 健脾去湿吃什么药 胰腺炎吃什么药见效快 便秘喝什么茶润肠通便
欧珀莱属于什么档次 暇步士属于什么档次 相位是什么 签证是什么 手镯断了有什么预兆
做梦梦到吵架是什么意思 什么时候才能够 多喝柠檬水有什么好处 掉头发多是什么原因 夏天穿什么衣服比较凉爽
纳豆是什么东西 雾化用什么药 脚底长鸡眼是什么原因 2月是什么星座的 茄子吃多了有什么坏处
无以言表什么意思hcv9jop5ns3r.cn 黑发晶五行属什么hcv8jop2ns2r.cn 嘴麻是什么原因引起的hcv9jop4ns0r.cn 餐饮行业五行属什么hcv9jop4ns7r.cn 珑字五行属什么hcv8jop7ns5r.cn
打无痛对身体有什么影响吗hcv8jop5ns1r.cn 红细胞分布宽度偏低是什么意思hcv7jop9ns5r.cn 备孕吃什么叶酸hcv8jop7ns0r.cn 今天是什么纪念日ff14chat.com 胃胀吃什么药hcv8jop2ns2r.cn
失眠吃什么中药0735v.com 红加黄等于什么颜色hcv9jop6ns1r.cn 子女缘薄是什么意思hcv9jop1ns1r.cn 伪骨科是什么hcv9jop4ns6r.cn ami是什么weuuu.com
胰腺炎挂什么科gangsutong.com karl lagerfeld是什么牌子hcv8jop4ns5r.cn 手指肿胀什么原因hcv8jop4ns9r.cn 布洛芬属于什么类药物hcv8jop3ns2r.cn 舌头麻木是什么原因hcv9jop5ns6r.cn
百度