【问题标题】:Using the line...file directive使用 line...file 指令
【发布时间】:2021-03-02 02:31:26
【问题描述】:

为什么有人想要使用#line 指令在程序中重置/更改当前行号或文件名的示例用法是什么,例如:

#line 10000 "somefile.c"
printf("File: %s, Line: %d", __FILE__, __LINE__)

什么是有用的例子?

【问题讨论】:

  • “某人”:通常不会。它旨在供从其他代码生成 C 代码的脚本或程序使用——这样,错误消息可以引用原始代码。 (此外,曾几何时,C 预处理器本身是一个单独的程序,它使用 #line 的等价物在 #include 处理之前将原始行号传递给编译器本身。)
  • 在自动生成的 c 代码中,将代码从一个源文件转换为另一个源文件时。当生成的文件中有错误时,您通常想知道原始源文件中的哪一行创建了错误。它通常由 c 预处理器生成。
  • 无论好坏,我从事的项目的一部分有一个由cat file1.c file2.c … file9.c > code.c 创建的源文件。每个组件文件的顶部都有#line 2 "file1.c" 或等效项,因此来自复合code.c 的编译错误将错误归因于正确的源文件。我必须通过创建code.c 作为包含#include "file1.c" #include "file2.c" ... #include "file9.c" 的普通签入文件来改进这一点,因此不再需要#line 指令,尽管它们也没有害处(除了碰撞文件中的行号减 1)。

标签: c c-preprocessor


【解决方案1】:

自动生成 C 代码的程序使用该指令(如 flex(1)yacc(1))来指示在原始源文件中插入代码的位置。

想象一下,您在一个文件中为yacc(1) 制定语法规范,该文件有时会插入到它生成的源文件 (yy.tab.c) 中,您提供给它的源代码将被逐字替换。 Yacc 引入了对它的源代码的引用,所以你可以回到原来的.y 文件看看你写的代码

如果你查看 yacc 创建的 C 源文件,你会发现类似的指令

#line 357 "myfile.y"
... /* your inserted code */
#line 20547 "yy.tab.c"
... /* more yacc generated code */
#line 380 "myfile.y"
... /* more literal code written by you */
#line 21250 "yy.tab.c"
...

因此调试器将插入对真实源文件的正确引用,而不是对 yacc 处理的中间 C 源文件的引用。

cpp 预处理器通过在#include <stdio.h> 扩展的开头插入一个#line 1 "stdio.h" 来指示文件的每次更改,并在从#include 返回时插入一个#line 37 "my_original_source.c" 以包含在调试器信息中源代码中的正确行。如果您只是预处理源代码,您可以看到这种情况发生:

cpp mysourcefile.c | more

你会看到一对#line指令包含入口和包含出口点,重置行计数器。

【讨论】:

  • 很棒的答案。非常感谢你。对了,开头的那几行是干什么用的,比如:# 1 "m.c" # 1 "<built-in>" # 1 "<command-line>" # 31 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4
  • 还有一件事。 #357 "myfile.y"#line 357 "myfile.y" 的简写吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 1970-01-01
  • 2017-06-05
  • 1970-01-01
  • 2017-01-13
相关资源
最近更新 更多