【问题标题】:Configure $(CC) to warn when inclusion is safe to be removed [closed]配置$(CC)以在可以安全删除包含时发出警告[关闭]
【发布时间】:2024-01-09 23:14:01
【问题描述】:

阅读此源代码文档:

// foo.c
#include<stdint.h>
main(){}

我可以这样做:

$ gcc -Wno-implicit-int foo.c
$ ./a.out
$ gcc -dumpversion
6.3.0

GCC 编译时没有警告。

让我们修改源代码:

// foo.c
main(){}

但同样的事情发生了:

$ gcc -Wno-implicit-int foo.c
$ ./a.out
$ gcc -dumpversion
6.3.0

输出是一样的。我想相信这意味着可以安全地删除包含。

我可以配置 GCC 以警告此类包含可以安全删除吗?

LLVM 也一样吗?

编译器的计算成本高吗?

您会考虑激活该功能吗?

【问题讨论】:

  • 我刚刚在第二个示例中使用gcc -Wall (Linux/Debian/Sid/AMD64) 尝试了 GCC 8.2。收到警告。您的 GCC 6 正在变旧。升级吧!
  • 编译器倾向于在出现错误时发出诊断(错误),并在代码可能不正确或不明确时发出警告。包含不需要的标头也不是——实际上,编译器通常甚至不会尝试检测是否可以删除“包含”,或者提供一个选项来警告这样的事情。
  • @BasileStarynkevitch 是 -Wno-implicit-int 抑制警告,不一定是编译器版本。我可以通过使用/不使用 gcc 7.3.1 上的选项来合成 OP 或您的结果
  • @Peter 好吧,我想这可以作为答案!
  • 这甚至不是有效的 C 代码。您的 main 缺少结果类型,自 19 年 (C99) 以来就不允许这样做。显式选项应该没有 ned..你是什么意思包含”?这与#include proprocessor 指令有什么关系?你为什么要禁用该警告?

标签: c gcc include llvm compiler-warnings


【解决方案1】:

扩展 Peter 的评论,我将解决第三个问题,即有关成本的问题。 TL;DR:这不是添加到编译器的简单功能。

目前,编译器只是逐行处理源代码,将#includes 视为一种获取不同源代码的方法,并将其插入到输入流中的适当位置。这一切都由预处理器处理。

它甚至添加了一些特殊指令(通常是#line),以便错误消息与它们实际发生的位置相匹配,但仅此而已。

执行 OP 要求的操作是为每个声明添加元数据,指定在哪个文件中找到它。然后在处理源时,有必要标记每个被使用的声明。最后在编译结束时,编译器将不得不遍历整个符号表,以查看是否有任何文件具有其中没有任何符号被使用过的条件。

这不是“五行代码”修复,这将是一笔相当大的投资。

我刚刚概述的内容并没有开始处理嵌套的#include。假设outer.c 包括middle.h。现在middle.h 中没有任何outer.c 中使用的符号,但它确实包含使用的inner.h。因此,如果不将“路线”保存到每个变量,您就有可能丢弃 middle.h 并因此失去 inner.h

【讨论】: