gpt4 book ai didi

c - 为什么预处理器禁止宏粘贴奇怪的标记?

转载 作者:行者123 更新时间:2023-12-05 08:46:47 24 4
gpt4 key购买 nike

我正在编写自己的基于 GCC 的 C 预处理器。到目前为止它几乎完全相同,但我认为多余的是对通过 ## 连接的标记执行任何形式的检查。所以在我的预处理器手册中,我这样写:

3.5 Concatenation

...

GCC forbids concatenation with two mutually incompatible preprocessingtokens such as "x" and "+" (in any order). That would result in thefollowing error: "pasting "x" and "+" does not give a validpreprocessing token" However this isn't true for this preprocessor - concatenationmay occur between any token.

我的推理很简单:如果它扩展为无效代码,那么编译器将产生错误,因此我不必显式处理此类情况,从而使预处理器变慢并增加代码复杂性。如果它生成有效代码,那么此限制删除只会使其更加灵活(尽管可能在极少数情况下)。

所以我想问一下,为什么实际上会发生这个错误,为什么实际上应用了这个限制,如果我在我的预处理器中取消它是否真的是犯罪?

最佳答案

就 ISO C 而言,如果 ## 创建无效 token ,则行为未定义。但是那里有一个有点奇怪的情况,在下面的方式中。 C 的预处理翻译阶段的输出是预处理标记流 (pp-tokens)。这些被转换为标记,然后进行句法和语义分析。现在这里有一条重要的规则:如果 pp-token 没有可以将其转换为 token 的形式,则违反约束。因此,您在没有 ## 运算符帮助的情况下自己编写的垃圾预处理器 token 必须被诊断为错误的词法语法。但是,如果您使用 ## 创建错误的预处理 token ,则行为未定义。

请注意这里的微妙之处:如果 ## 用于创建错误的预处理 标记,则其行为是未定义的。粘贴不是定义明确的,然后在 pp-tokens 转换为标记的阶段被捕获:从 ## 被评估的那一点开始它是未定义的。

基本上,这是历史性的。 C 预处理器在历史上(可能有些是)独立的程序,其词法分析与下游编译器不同并且更宽松。 C 标准试图以某种方式用具有翻译阶段的单一语言来捕捉这一点,结果有一些怪癖和可能令人惊讶的规范不足的领域。 (例如,在预处理翻译阶段,数字标记(“pp-number”)是一种奇怪的词法语法,它允许出现乱码,例如具有多个浮点 E 指数的标记。)

现在,回到您的情况。您的文本 C 预处理器实际上并不输出 pp-token 对象;它输出另一个文本流。您可能在内部有 pp-token 对象,但它们在输出时会变平。因此,您可能会想,为什么不允许您的 ## 运算符只是盲目地将任意两个标记粘合在一起?最终效果就好像这些标记被转储到输出流中而没有任何中间空格。 (在支持 ## 并作为单独程序运行的早期预处理器中,这可能就是全部内容)。

不幸的是,这意味着您的## 运算符不是纯粹的善意 标记粘贴运算符;它只是一个盲目并置运算符,有时会产生一个标记,当它恰好并置两个将被下游编译器作为一个词法分析的标记时。如果您采用这种方式,最好是诚实并记录下来,而不是将其描述为一种灵 active 功能。

另一方面,拒绝 ## 运算符中错误的预处理标记的一个很好的理由是捕捉它无法实现其记录的工作描述的情况:制作一个标记的要求两个。这个想法是程序员知道语言规范(程序员和实现之间的契约)并且知道 ## 应该制作一个 token ,并依赖于它。对于这样的程序员,任何涉及错误标记粘贴的情况都是错误的,最好通过诊断来支持该程序员。

GCC 和 GNU CPP 预处理器的维护者可能持有这样的观点:预处理器不是一个灵活的文本修改工具,而是支持严格的 C 编程的工具链的一部分。

此外,错误的 token 粘贴作业的未定义行为很容易被诊断出来,那么为什么不诊断呢?标准中缺少这方面的诊断要求看起来只是一个历史性的让步。它是一种诊断的“唾手可得的果实”。让那些难以诊断或难以诊断或需要运行时惩罚的未定义行为未被诊断。

关于c - 为什么预处理器禁止宏粘贴奇怪的标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69051959/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com