Pav*_*kin 1 c token string-literals language-lawyer c-preprocessor
双引号 ( ") 是预处理标记还是未终止的字符串文字?
C11,6.4 词汇元素,语法,1:
preprocessing-token:
header-name
identifier
pp-number
character-constant
string-literal
punctuator
each non-white-space character that cannot be one of the above
Run Code Online (Sandbox Code Playgroud)
C11,6.4.5 字符串文字,语法,1:
string-literal:
encoding-prefix(opt) " s-char-sequence(opt) "
Run Code Online (Sandbox Code Playgroud)
注意:GCC 认为它是未终止的字符串文字:
#if 0
"
#endif
Run Code Online (Sandbox Code Playgroud)
产生:
warning: missing terminating " character
Run Code Online (Sandbox Code Playgroud)
C 2018 6.4.1 3 表示预处理标记的一类是 \xe2\x80\x9c 单个非空白字符,它们在词法上与其他预处理标记类别 \xe2\x80\x9d 不匹配,下一句表示 \xe2\ x80\x9c如果一个\xe2\x80\x99或一个"字符与最后一个类别匹配,则行为未定义。\xe2\x80\x9d 因此,如果"出现孤立的字符(未与另一个字符配对"且其之间有s-char 序列的字符),则会失败匹配字符串文字的词汇形式,并被解析为与其他类别不匹配的单个非空白字符,并且该行为不是由标准定义的。这解释了 GCC 消息。
(我注意到 6.10.2 3# include使用 \xe2\x80\x9c " q-char-sequence " new-line \xe2\x80\x9d 描述了指令。但是,6.10 1 中的早期语法将指令描述为 \xe2\x80\x9c # include pp-tokens new-line \xe2\x80\x9d。我对此的解释是该指令被解析为具有预处理器标记,特别是字符串文字,并且 6.10.2 3 表示如果该字符串文字具有以下形式显示为 \xe2\x80\x9c " q-char-sequence " \xe2\x80\x9d,则它是# include该段落正在讨论的类型的指令。)