1

我有一个 C 文件(为简单起见,假设它不包含任何内容)。这个 C 文件需要几个文字数字的定义才能正确编译 - 我想弄清楚这些是哪些定义。

自然地,我们可以尝试编译该文件,但在某些时候我们会开始出现故障;通过一些故障恢复,我们可能会收到有关其他定义的故障通知。但是 - 这不是我想要的:

  • 我对完成程序的编译不感兴趣。构建一个语法树(甚至是某种简化的语法树)就足够了。
  • 我可以假设,除了缺少宏之外,该程序在语法上是正确的。对于 C 来说,这应该意味着它在语法上是正确的,句号。
  • 我可以假设相关的宏都是大写的,即它们的形式是[A-Z][A-Z_0-9]*)。

获取未定义宏列表的替代方法是什么?

动机:实际上,我正在将一些东西输入动态编译库,并且我想事先检查是否已定义所有必要的宏,而不知道先验文件需要哪些宏(即,对​​于不同的输入文件可能是不同的宏)。

4

2 回答 2

1

丑陋的后备解决方案:

显然,你的后备是只编译程序。但是 - 这样做的同时尽量减少不相关的消息和不相关的消息。这将取决于编译器,但以 GCC 为例,您可以:

  • 避免任何输出生成
  • 禁止警告
  • 抑制注释
  • 严格符合标准,没有 GNU 扩展
  • 禁用GCC 坚持使用的那些愚蠢的引号

...使用各种命令行开关并使其从标准输入流而不是文件中获取输入(到目前为止我发现的唯一方法是抑制一些注释)。看起来像:

  cat your_program.c \
|  LC_CTYPE=C gcc -std=c99 -fsyntax-only -x c -fcompare-debug-second -

输出可能如下所示:

<stdin>: In function 'mult':
<stdin>:3:18: error: 'MY_CONSTANT' undeclared (first use in this function)

现在,如果您的程序除了未定义的宏(= 未声明的标识符)之外是正确的,那么您可以使用一些 shell 脚本轻松解析上述内容:

  cat your_program.c \
| LC_CTYPE=C gcc -std=c99 -fsyntax-only -x c -fcompare-debug-second - \
| sed -r '/error: /!d; s/^.*error: '"'//; s/'.*//;" \
| sort -u

这还有一个缺点是不能完全嵌入到您的程序中,即您不能在您的某些程序中使用某些库调用部分编译,然后以编程方式解析输出。你需要一个system()-type 调用。

注意:如果您的程序可能有其他错误,则在命令中删除该行的模式sed需要更具体一些。

于 2021-06-01T16:24:33.710 回答
0

您可以使用一些想法,即必须在某处声明 C 文件中注释之外的每个类似标识符的非关键字。(我想!对吗?)

基本思想是生成此类标识符的列表并搜索程序,然后搜索包含的标头以获取每个标识符的声明。虽然这可以手动和临时完成,但索引所有潜在的头文件并使用 ctags 之类的东西进行索引和查找可能是有意义的(正如我刚刚了解到的那样,有一个 libctags)。

我认为解决方案不一定是完美的——错过的案例只会导致编译失败——但你想减少这样的案例。在这种情况下,标识符源代码的解析不必是完美的(它可以忽略嵌套注释等),并且可以通过可接受的努力“手动”完成。

于 2021-06-01T17:17:37.683 回答