在C ++ 11中2.5预处理标记[lex.pptoken]:
如第16条所述, 在翻译阶段4的某些情况下,空格(或缺少空格)不仅仅是预处理标记分离。
这指的是哪种情况?
答案 0 :(得分:8)
在第4阶段,有几次空白是重要的:
每个预处理指令都以#
标记开头,该标记“是源文件中的第一个字符......或者是包含至少一个换行符的空格。”每个预处理指令都以换行符结尾。
在类似函数的宏定义中,以参数列表开头的左括号必须紧跟在命名宏的标识符后面。它们之间一定不能有空格。
例如,指令#define F()
定义了一个类似函数的宏,它扩展为空,而指令#define F ()
定义了一个类似于对象的宏,它扩展为()
。
在宏替换期间评估#
运算符时,会在字符串化期间考虑空白。要进行字符串化的标记之间的空格序列将折叠为结果字符串文字中的单个空格。
例如,字符序列f(x)
被字符串化为"f(x)"
,但字符序列f ( x )
被字符串化为"f ( x )"
,即使它们之间没有语义差异两次宏观更换后。
请注意,在阶段2中删除了转义的换行符,并且在阶段3中每个注释都被单个空格字符替换。这两个字符都发生在阶段4之前,因此在阶段4期间,转义的新行不计算在内作为一个新线,一个评论与空间角色无法区分。
答案 1 :(得分:1)
所有的空白区域都是 等同于预处理期间的某些情况(参见 cpp.stringize 中的#字符串文字创建运算符,用于 例子)。
您可以阅读The # Operator [ccp.stringize] here。以下是相关信息:
如果在替换列表中,参数前面紧跟a
#
预处理令牌,都被单个字符串替换 文字预处理标记,包含相应参数的预处理标记序列的拼写。参数的预处理标记之间每次出现空格 成为字符串文字中的单个空格字符。 第一个预处理令牌之前和之后的空格 删除包含参数的预处理令牌。除此以外, 参数中每个预处理标记的原始拼写是 保留在字符串文字中,但特殊处理除外 用于生成字符串文字和字符文字的拼写: 在角色的每个\
和"
字符之前插入\
个字符 文字或字符串文字(包括分隔"
个字符)。如果 结果的替换不是有效的字符串文字, 行为未定义。#
和##
运算符的评估顺序未指定。