ISO/IEC 9899:2011 条款6.10——预处理指示符

时间:2021-05-05 03:08:24

6.10 预处理指示符

语法

1、preprocessing-file:

groupopt

group:

group-part

group    group-part

group-part:

if-section

control-line

text-line

#    non-directive

if-section:

if-group    elif-groupsopt    else-groupopt    endif-line

if-group:

#    if    constant-expression    new-line    groupopt

#    ifdef    identifier    new-line    groupopt

#    ifndef    identifier    new-line    groupopt

elif-groups:

elif-group

elif-groups    elif-group

elif-group:

#    elif    constant-expression    new-line    groupopt

else-group:

#    else    new-line    groupopt

endif-line:

#    else    new-line

control-line:

#    include    pp-tokens    new-line

#    define    identifier    replacement-list    new-line

#    define    identifier    lparen    identifier-listopt    )    replacement-list    new-line

#    define    identifier    lparen    ...    )    replacement-list    new-line

#    define    identifier    lparen    identifier-list    ,    ...    )    replacement-list    new-line

#    undef    identifier    new-line

#    line    pp-tokens    new-line

#    error    pp-tokensopt    new-line

#    pragma    pp-tokensopt    new-line

#    new-line

text-line:

pp-tokensopt    new-line

non-directive:

pp-tokens    new-line

lparen:

一个(字符,没有空白符立即放在它之前

replacement-list:

pp-tokensopt

pp-tokens:

preprocessing-token

pp-tokens    preprocessing-token

new-line:

换行字符

描述

2、一个预处理指示符由一串预处理满足以下约束的预处理符记组成:在序列中的第一个符记是一个 # 预处理符记,(在翻译阶段4的开头)它要么是在源文件中的第一个字符(可选地,在不包含换行字符的空白符之后),要么跟在至少包含一个换行字符的空白符之后。在该序列中的最后一个符记是跟在第一个符记之后的第一个换行字符。[注:从而,预处理器指示符通常被称为“行”。这些“行”不具有其它语法意义,由于所有空白符都是等价的,除了在预处理期间的某些情况下(比如见6.10.3.2中的#字符串字面量创建操作符)。]一个换行字符终结预处理指示符,即使它在一个类似函数的宏的调用内发生。

3、一个文本行不应该用一个 # 预处理符记开头。一个非指示符不应该以出现在语法中的任何指示符名开头。

4、当一个组被跳过(6.10.1)时,指示符语法对于允许任一序列的预处理指示符在指示符名与跟在其后的换行字符之间发生是松弛的。

约束

5、在一个预处理符记内,预处理器符记之间应该出现的仅有的空白字符(从引入#预处理符记到用于终结的换行字符之前)是空格与水平制表符。

语义

6、实现可以根据条件处理并跳过源文件片段,包括其它源文件,以及代替宏。这些特性称为预处理,因为概念上它们在产生翻译单元的翻译之前发生。

7、在一个预处理指示符内的预处理符记不属于宏扩展,除非在其它地方阐明。

8、例 在以下代码片段中

#define EMPTY
EMPTY # include <file.h>

在第二行的预处理符记序列不是一个预处理指示符,因为它并没以一个 # 在翻译阶段4开头,即使它在宏EMPTY被代替后会如此。

6.10.1 条件包含

6.10.2 源文件包含

6.10.3 宏替换

6.10.4 行控制

6.10.5 错误指示符

6.10.6 pragma指示符

6.10.7 空指示符

6.10.8 预定义的宏名

6.10.9 Pragma操作符