gpt4 book ai didi

c - 反斜杠-换行符组合如何影响 C 预处理器的 __LINE__ 宏的值?

转载 作者:行者123 更新时间:2023-12-03 09:35:22 26 4
gpt4 key购买 nike

根据 C 标准,折叠由反斜杠-换行符序列连接的多个物理行是比执行预处理器更早的转换阶段。
假设没有因较早的 #line 而引起的并发症然后,指令执行 __LINE__ 的值宏在此类线拼接之前反射(reflect)物理线号?这就是你会发现的,例如通过手动检查源代码或文本编辑器将第 # 行报告为什么,这可能是更有用的替代方法。或者它是否反射(reflect)了拼接之后的 # 行,这可能是预处理器在标准中实际指定的翻译阶段顺序下实际看到的?
(如果我理解正确——我很可能不会——预处理器将无法知道给定的行是否是拼接的产物。)

最佳答案

编译器实现 __LINE__通过以 C 标准未指定的方式记住物理行号。
C 2018 6.10.8.1 1 告诉我们 __LINE__替换为“当前源行的假定行号(在当前源文件中)(整数常量)。”该规范含糊不清,无法在严格遵守标准的同时以有用的方式实现。
考虑这个代码:

#define Assert(test) do { if (!test) printf("Assertion on line %d failed.\n", __LINE__); } while (0)

... Many lines of code follow, including some with line splicing.

Assert(condition);

... Many lines of code.
为了有用,此代码必须打印 Assert 所在的物理行号。用来。它需要是物理行号,以便用户可以在文本编辑器中定位该行,并且它需要是 Assert 所在的行。宏被替换,而不是定义,因为那是检测到问题的地方。 GCC 和 Clang 都这样做。
但是,这需要来自 的物理行号。之前 宏替换期间提供线路拼接,发生 线拼接。在 C 2018 5.1.1.2 1 中,标准规定了一个翻译模型,其中:
  • 在第 2 阶段,“删除后跟换行符的反斜杠字符 () 的每个实例,拼接物理源代码行以形成逻辑源代码行,”和,
  • 在第 3 阶段,“源文件被分解为预处理标记和空白字符”,包括换行符但不包括第 2 阶段删除的字符,以及,
  • 在第 4 阶段,宏调用被扩展。

  • 因此,如果编译器替换了 __LINE__阶段 4 中的宏实际上只有预处理标记和剩余的空白字符,它无法知道要提供的物理行号。
    因此,编译器不能按照标准的翻译模型逐字实现。为了有用,它必须将物理行号与可能是宏名称的每个预处理标记相关联。每当替换宏时,它必须传播关联的物理行号。然后,当 __LINE__ token 最终被替换,编译器将使用关联的物理行号来替换它。

    关于c - 反斜杠-换行符组合如何影响 C 预处理器的 __LINE__ 宏的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65101660/

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