【发布时间】:2022-01-23 14:18:24
【问题描述】:
最近我尝试在我的项目中实现头文件系统,结果很糟糕。
我的主要不满是:
- 应该如何跟踪哪些 .h 文件具有需要编译成对象的对应 .c 文件,以及哪些 .h 文件是单独的?
- 查看 GNU C 库的代码,很明显,头文件会导致代码不可读和(可能)不可维护
- 每次添加新的头文件时都在编译命令中添加一个.c文件很烦人
- 不得不编写两个文件是令人厌烦的——一个是宣布你将在未来提供一个 .c 文件的承诺(这些函数原型或任何它们非常不直观),然后在.c 文件。最糟糕的事情 - 你不能遵循代码,因为 .h 文件(你将在 main.c 中遇到)没有以任何方式链接到它的 .c 文件。但与此同时,.c 文件由于某种原因包含了它的 .h 文件(如果它们存在,可能是为了获取所需的宏)
另一方面,我确实了解以下情况需要头文件系统:
- 避免循环依赖
- 区隔化
- 避免冗余
所以我想知道头文件修复的事情是否可以通过其他更直观、更易读、更轻松的方式来完成?
例如,如果我们将 ifndef 部分添加到 .c 文件中,我们可以包含其他 .c 文件。
//main.c
#include "special.c"
//special.c
#ifndef SPECIALC
#define SPECIALC
#include <stdio.h>
void some_func(void){puts("hello")};
#endif
看起来不错。现在您可以从字面上跟踪线索,而不必担心需要跟踪哪些 .c 文件需要附加到编译命令。
但我知道这不会像我想象的那么好。但我只是想展示一个理想的解决方案如果可行的话会是什么样子。
也许你知道一些接近这个理想的解决方案。
【问题讨论】:
-
不要
#include源文件。将所有源文件构建为目标文件,然后将它们链接在一起。使用 Make 等构建工具或 CMake 等元构建工具。即使是“小”项目,它也会为您提供帮助。 -
您是否考虑过使用 IDE 来维护您的项目?
-
对于一个小项目,您可以在头文件中实现所有内容,然后只编译 main.c。对于一个非常小的项目来说,增加的重新编译时间应该不是问题,如果这不起作用,则意味着您的项目对于仅标题定义来说已经太复杂了。
-
那么...当一个新人加入您的团队并开始在
special.c中编写实际(实现)代码时会发生什么?事情会继续构建和运行吗? -
您可以通过 (ab) 使用 inline specifier 在某种程度上摆脱 C++ 中仅包含标头的库。如果这是一件好事还是坏事是另一个问题,但长话短说 - 有时会使用它,例如参见 boost::process。
标签: c