在每个源文件中包含一个头文件。

9
假设你有数百个源文件(.c或.cpp文件),并且您希望在每个源文件中包含一些定义、函数/变量声明。通常在C/C++中,我们使用头文件来实现此目的。但是在这种情况下,您需要在每个源文件中放置#include“header.h”。那么我的问题是,是否有一种方法可以为所有文件包含一个头文件,而不必在每个文件中加入#include “header.h”,因为为数百个源文件编写#include “header.h”将非常繁琐。

2
不可以,但是你可以编写一个Python脚本,在大约5分钟内为您完成此操作。 - TJD
@TJD,不是吗?你肯定可以做到。 - Carl Norum
@CarlNorum,有趣的是,我不知道“-include”选项。 - TJD
4个回答

15
你可以使用clang或GCC的-include标志。从man页面中得知: -include 文件名文件名当作若干源代码文件的第一行,使它们隐式地被包含在每个文件中。然而,寻找文件名的第一个目录是预处理器的工作目录,而不是包含主源代码文件的目录。如果在该目录中没有找到,则按照正常的"#include "...""搜索链的剩余部分继续查找。
如果给出了多个-include选项,则按照它们在命令行上出现的顺序包含这些文件。
示例:
clang -include header.h -c file1.c
clang -include header.h -c file2.c
clang -include header.h -c file3.c
clang -o app file1.o file2.o file3.o

MSVC有/FI标志,它类似于/include


是的,我只使用clang或者gcc进行编译。但是我在网上找不到任何示例。你介意分享一个给我吗?谢谢。 - pythonic

3
您可以使用Unix管道来解决这个问题。
find ./ -name "*.c" -or -name "*.cpp" | xargs -n 1 sed -i '1 i #include <my_header.h>'

1

你不能这样做,但是你可以编写一个脚本来实现。一个脚本可以遍历每个文件,并在顶部写入#include "header.h"编辑:-include在gcc中可以实现此功能。

然而,通过编译器选项,您可以以不同的方式实现所需的功能。在gcc中,使用-D

假设您想要在所有源文件中将定义DEBUG_LEVEL设置为2。您只需像这样调用gcc:

gcc -DDEBUG_LEVEL=2

请注意,在这种情况下,您需要重新构建整个项目(如果您已经更改了所有源文件都依赖的1个头文件中的此定义,则无论如何都必须这样做)。

是的,我知道-D选项,但它只是头文件中#define的替代品。通常,头文件中还有其他内容,例如声明、宏等。 - pythonic

0

头文件不是定义,它们只是声明。

尽可能少地放入头文件 - 这样可以节省编译器的工作量,也可以减少相互依赖性。

你甚至可以通过在这些头文件中使用前向声明来进一步减少数量。

如果你聪明的话,你可以让你的 IDE 帮助你填补空缺,而不是伤害你的手指。


头文件不是定义,它们是声明。通常它们是混合的:对于需要可执行空间的内容,它们倾向于是声明,但对于类、模板、内联函数等内容,则是定义。提前声明是不好的做法,你应该优先选择一个额外的提前声明头文件,例如标准库的<iosfwd>,这样包含层次结构可以确保一致性和声明组件的所有权,它确保了在类型被替换为特定模板实例化的typedef时重新编译的工作。 - Tony Delroy
@TonyDelroy 在我看来,对于头文件来说,要求客户端以特定顺序包含头文件,或者在头文件中包含其他头文件,或者将头文件作为单块而不是分成逻辑上设计良好的模块,这些都是不好的编程实践。为了避免这些问题,通常需要使用前向声明。我不知道前向声明有什么不利之处。 - bames53
@TonyDelroy - 我曾经参与过非常大型的项目,你需要在编写代码之前就决定这些事情。这样可以节省开发、测试和检查成本。在C++上下文中,前向声明是简单地使用“class X;”而不是“#include <x>”,这意味着如果类X发生变化,您不需要重新编译大量的内容。对于程序员来说,这可能需要几个小时的停机时间。请去书店看看Scott Myers的好解释。 - Ed Heal
@TonyDelroy 我认为你提到的问题是特定于不正确地进行前向声明。例如,通常情况下,您不能前向声明您不负责定义的内容。例如,一些boost库尝试在std中前向声明某些内容,但这实际上是不允许的,并且会与libc ++发生冲突。拥有专用的前向声明头文件是一个好主意,可以解决这个问题(我会豁免*fwd头文件不受“无头文件嵌套”的规则限制)。 - bames53
@Ed Heal:你只是重复了所有显而易见的表面问题,而没有解决前向声明头文件的原因——它只是一个包含“class X;”(或适当的内容)的小头文件,但与正常的头文件和实现一起维护。我已经读过Meyers的书,谢谢。 - Tony Delroy
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接