8

我有一个代码生成器,它将获取一些用户编写的代码并将其块嵌入到一个更大的生成文件中。我希望底层编译器在用户代码中存在缺陷时提供良好的诊断,但我也不希望生成的代码中的缺陷在不应该被错误归因于源时。

我打算#line lineNum "sourceFile"在每个用户编写的代码块的开头发出指令。但是,一旦我离开用户提供的代码,我找不到任何#line提及“重置”技术__LINE____FILE__返回到生成文件中的实际行的指令文档。理想的解决方案类似于 C# 预处理器的#line default指令。

我是否只需要跟踪我写了多少行并自己手动重置?还是有更好的方法,我可以传递某种重置指令或哨兵值#line来消除与用户代码的关联?

看起来这可能是以前提出的,尽管那里没有可靠的答案。为了区分这一点,我还要询问 C++11 中缺少答案的情况是否发生了变化。

4

5 回答 5

7

我以前使用过的一种技术是,当我的代码生成器#想要重置行指令时,它自己在一行上输出 a,然后使用简单的 awk 脚本对文件进行后处理并将其更改为正确的行指令:

#!/bin/awk -f
/^#$/ { printf "#line %d \"%s\"\n", NR+1, FILENAME; next; }
{ print; }
于 2013-02-12T02:25:09.150 回答
2

是的,您需要跟踪已输出的行数,并且您需要知道要输出到的文件的名称。请记住,您指定的行号是下一行的行号。所以如果到目前为止你已经写了 12 行,你需要 output #line 14 "filename",因为 #line 指令将在第 13 行,所以下一行是 14。

和中的#line预处理器指令没有区别。CC++

于 2013-02-12T01:54:49.993 回答
0

假设代码生成器的输入“user.code”包含以下内容:

int foo () {
   return error1 ();
}

int bar () {
   return error2 ();
}

假设你想增加它,所以它看起来基本上是这样的:

int foo () {
   return error1 ();
}

int generated_foo () {
   return generated_error1 ();
}

int bar () {
   return error2 ();
}

int generated_bar () {
   return generated_error2 ();
}

除非你不想那样。您希望向#line生成的代码添加指令,以便编译器消息指示错误/警告是来自用户代码还是来自自动生成的代码。该#line指令指示下一行代码的来源(而不是包含该#line指令的行)。

#line 1 "user.code"
int foo () {
   return error1 ();
}

#line 7 "generated_code.cpp"  // NOTE: This is line #6 of generated_code.cpp
int generated_foo () {
   return generated_error1 ();
}

#line 5 "user.code"
int bar () {
   return error2 ();
}

#line 17 "generated_code.cpp" // NOTE: This is line #16 of generated_code.cpp
int generated_bar () {
   return generated_error2 ();
}
于 2013-02-12T01:56:18.207 回答
0

@Novelocrat,

我之前在这里问过这个问题,并没有发布可靠的答案,但我发现如果在指向用户代码的自动生成的代码中插入行指令,那么这会使自动生成的代码难以重新定位。您必须将自动生成的代码和用户代码保存在编译器可以找到它们以报告错误的位置。我认为最好在生成的代码中简单地插入用户代码的文件名和行号。在好的文本编辑器中,通过将光标放在文件名上,只需几次击键即可跳转到文件中的一行。

例如:在 vim 中,将光标放在文件名上并按下会将g-f您带到文件,然后:42将您带到出现错误的第 42 行(例如)。

Just posting this bit here, so that someone else coming up with the same questions might consider this alternative too.

于 2013-03-29T05:51:24.240 回答
-1

你试过什么__LINE____FILE__给你什么?我相信它们是从您的#line指令中提取的(如果不是,那有什么意义?)。

(使用 gcc-4.7.2 和 clang-3.1 进行的快速测试证实了我的预感)。

于 2013-02-12T02:02:28.167 回答