2026西湖龙井茶官网DTC发售:茶农直供,政府溯源防伪到农户家
简介
与 Go 语言不同,Go 的语言定义通过其编译器严格强制要求包含模块(即,精确包含你所使用的内容,不多不少),而 C 和 C++ 的语言定义中都没有类似的强制机制。这可能导致两个问题:
如果你不必要地包含了一个不需要的头文件(即,没有引用其中的任何符号),那么编译速度会稍微变慢。对于小型代码库,这种影响可以忽略不计;但对于构建时间可能长达近一小时甚至超过一小时的大型代码库来说,这就很重要了。
如果你没有直接包含所需的头文件(即,引用了其中一个或多个符号),那么当你移除一个看似无关的
#include时,构建可能会失败。或者,你的程序可能在一个平台上构建正常,但在另一个平台上由于系统头文件的细微差异或#ifdef条件编译指令而失败。
为了避免这两个问题,你应该遵循“用即包含”原则,即源文件应满足以下条件:
对于其引用了符号的每个头文件,都直接且仅包含一次。
不包含任何未引用其中符号的头文件。
虽然你可以尝试手动遵守这一原则,但随着项目中包含或使用的头文件数量增加,这会变得非常困难。
你可能会认为应该有某种方法来自动检查源文件是否违反该原则——确实有。经过短暂的搜索,我找到了 include-what-you-use。
include-what-you-use
找到 include-what-you-use(简称 iwyu)后,我试用了一下。它勉强能运行,但给出了错误的建议。例如,当通过 Gnulib 使用 getopt_long 时,它提示我需要包含 getopt-ext.h。虽然从技术上讲这是正确的(因为 Gnulib 中声明 getopt_long 的文件确实是这个),但该文件属于 Gnulib 的实现细节,用户不应知晓或关心;用户仍然应该只包含 getopt.h。Iwyu 提供了一种通过“映射文件”来修复此问题的方法,但必须手动操作令人烦恼。
在我看来,如果你包含了一个标准(或类标准)头文件如 getopt.h,那么 getopt.h 所包含的任何头文件都应被视为实现细节。也就是说,getopt.h 应自动作为其所包含头文件的代理,以便在这些其他头文件中声明的任何符号都应被视为在 getopt.h 中声明。
由于 C、C++ 和 POSIX 标准头文件的集合是已定义的,因此由任何一个标准头文件包含的其他头文件都应自动被视为实现细节,且标准头文件应自动代理这些其他头文件。
除此之外,我发现 iwyu 在其他几个方面也不够理想:
部分配置通过上述的映射文件完成,而其他配置则通过源代码中的特殊
IWYU注释完成。Iwyu 自 2011 年起就已存在。截至本文撰写的 2026 年,th
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。