根据 C 标准,折叠由反斜杠-换行符序列连接的多个物理行是比执行预处理器更早的转换阶段。
假设没有由于较早的#line指令引起的并发症,那么__LINE__宏的值是否反映了之前的物理行号拼接这些线?这就是您会发现的内容,例如通过手动检查源代码或文本编辑器将第 # 行报告为的内容,并且可能是更有用的替代方法。或者它是否反映了拼接之后的 # 行,这可能是预处理器在标准中实际指定的翻译阶段顺序下实际看到的?
(如果我理解正确——我很可能不会——预处理器将无法知道给定的行是否是拼接的产物。)
__LINE__编译器通过以 C 标准未指定的方式记住物理行号来实现。
C 2018 6.10.8.1 1 告诉我们__LINE__被替换为 \xe2\x80\x9c 当前源代码行(整型常量)的假定行号(在当前源文件内)。\xe2\x80\x9d 这个规范是模糊的,不能以有用的方式实施,同时严格遵守标准。
考虑这段代码:
\n#define Assert(test) do { if (!test) printf("Assertion on line %d failed.\\n", __LINE__); } while (0)\n\n... Many lines of code follow, including some with line splicing.\n\n Assert(condition);\n\n... Many lines of code.\nRun Code Online (Sandbox Code Playgroud)\n为了有用,此代码必须打印使用的物理行号Assert。它需要是物理行号,以便用户可以在文本编辑器中找到该行,并且它需要是宏Assert被替换的行,而不是定义的行,因为这是检测到问题的地方。GCC 和 Clang 都这样做。
然而,这要求在宏替换期间提供线路拼接之前的物理线路号,宏替换发生在线路拼接之后。在C 2018 5.1.1.2 1中,该标准指定了一个翻译模型,其中:
\n因此,如果编译器__LINE__在第 4 阶段替换宏并且实际上只有预处理标记和剩余的空白字符,则它无法知道要提供的物理行号。
因此,编译器不能按照字面上的标准\xe2\x80\x99s 翻译模型来实现。为了发挥作用,它必须将物理行号与每个可能是宏名称的预处理标记相关联。每当替换宏时,它都必须传播关联的物理行号。然后,当__LINE__最终替换令牌时,编译器将用关联的物理行号来替换它。
| 归档时间: |
|
| 查看次数: |
100 次 |
| 最近记录: |