C预处理器中的单个非空白字符

C预处理器中的单个非空白字符,c,c-preprocessor,C,C Preprocessor,根据C11标准草案N1570,§6.4/3: […]预处理标记的类别有:头名称、标识符、, 预处理数字、字符常量、字符串文字、, 标点符号和单个不带空格的非空格字符 在词汇上匹配其他预处理标记类别。69)如果是“或” “字符与最后一个类别匹配,行为未定义。[…] 69)在翻译阶段4(见6.10.3.3)内部使用了另一个类别placemarkers;它不能出现在源文件中 (我的重点。) 我找不到有效的方法来编码包含有效预处理标记的程序。“您突出显示的文本指出,如果“or”的使用方式使其成为单个非空

根据C11标准草案N1570,§6.4/3:

[…]预处理标记的类别有:头名称、标识符、, 预处理数字、字符常量、字符串文字、, 标点符号和单个不带空格的非空格字符 在词汇上匹配其他预处理标记类别。69)如果是“或” “字符与最后一个类别匹配,行为未定义。[…]

69)在翻译阶段4(见6.10.3.3)内部使用了另一个类别placemarkers;它不能出现在源文件中

(我的重点。)


我找不到有效的方法来编码包含有效预处理标记的程序。

您突出显示的文本指出,如果“or”的使用方式使其成为单个非空白字符预处理标记,则程序无效(即“行为未定义”)因此,没有自尊心的编译器会允许你这样做;编译器当然没有任何义务去做任何你可能认为有明确的未定义行为的事情。

单一的非空格字符可以是货币符号,如$$、英镑、美分或欧元,或者是背书或AT符号。那些用
\z
表示法的也可以。引号让我感到困惑。预处理器标记,我不知道它怎么能有一个引号既不是字符常量的一部分,也不是字符串文字的一部分。我最近的猜测是看到
\'
\“
在字符串或字符常量之外;但我还远远没有被说服。反斜杠属于另一类;然后,引语作为字符串或字符的一部分独立存在。它被否决,因为你的问题很难理解。我之所以理解它,是因为我在C11草稿中搜索了您提供的报价,并用完整的报价替换了您的报价。下次,花点时间添加足够的信息并正确设置问题的格式。(关于
#定义一个“
)这就是重点。预处理器基本上基于空格标记,并将字符串识别为单个标记。但不匹配的引号不能是有效的标记。可能对不匹配的
?(可能不需要这样做)我的期望是
定义一个
不应该工作-这是一个不完整的字符串文本。我也不会想出任何其他的方法,用宏的替换文本生成引号。但我可能缺乏想象力和/或咖啡因。在GCC 6.3.0中,即使没有请求编译警告,
#定义一个“
生成:
警告:缺少终止字符”
,因此这似乎是编译器允许的一种方式,“但是它在语法上是无效的,所以其他编译器可能会以不同的方式对待它。”JonathanLeffler当Per Bothner、Neil Booth和我在1999-2001年重写GCC的预处理器时,我们做出了一个设计决策,即尽可能多的预处理器时间UB实例将被视为及时诊断的编译错误。我认为UB的这个特殊实例是为了允许旧的预处理器不诊断
#定义一个“
”未定义的行为“通常意味着委员会无法想出任何合理的行为,因此他们将其留给编撰者。但我也不知道编译器如何证明以有效代码的形式悄悄地传递它是正确的。不过,我打赌这是一个故障保护,因为单个
可能不会被字符串文本解释器例程捕获。