有没有办法检测何时“意外”满足文件依赖性?

时间:2011-07-17 08:54:56

标签: c header include

假设有三个标题AAA.hBBB.hMyLib.hMyLib.h需要同时包含AAA.hBBB.h才能正常运作。

现在,恰好BBB.h中还包含AAA.h,但这完全取决于实施,MyLib.h不应该关注的细节。

然而,错误地,MyLib.h的作者忽略了包括AAA.h而从未注意到。据我所知,这通常不会导致错误或警告。稍后,有人会更改BBB.h的实施细节,以便不再需要AAA.h,从而将其删除。现在MyLib没有编译,因为库BBB的内部已经改变了。

在这些情况下,有没有办法出错或发出警告?我怀疑(如果这是可能的话)它将在包含的标题中采用某种注释。

2 个答案:

答案 0 :(得分:2)

您正在说明为什么包含标题作为导入名称空间的方法很糟糕。

我看到的唯一解决方案是纪律。标准库函数要求您包含相应的标题,您的项目应采用相同的标准。 MyLib.h之类的标题应仅包含它定义的类型及其函数原型。如果它需要使用某种类型来完成它的工作,那么应该明确地包含标题,所以如果它需要来自AAA的定义,它应该包含AAA.h,如果需要来自{{1}的定义它应该包含BBB,同样任何实现文件(假设BBB.h)都应明确包含它使用的任何定义的所有标头,而不管是否MyLib.c将它们包括在内好。 永远不要假设标题通过包含其他标题来隐式定义任何内容

使用IDE可以轻松检查,这通常会告诉您名称的定义位置,因此您可以轻松找出要使用的包含文件。可能有工具可以进行这种检查。

答案 1 :(得分:2)

我认为最好避免依赖公共接口标头中的其他标头,以免出现此问题。

公共接口标头不应包含不必要的定义。

在没有包含文件的情况下,有各种各样的技巧。例如,如果您只需要一个指针(仅定义typedef的库,那么您可以手动声明struct标签),并且可以使用_Bool代替bool来避免<stdbool.h>。遗憾的是,许多重要类型(例如size_tuint32_t)仅在标题中定义。

有些软件包甚至使用configure定义自己的foo_uint32_t,因此他们不需要在公共接口头中包含<stdint.h>。这非常棘手,因为类型必须完全相同才能避免混淆:即使sizeof(unsigned int) == sizeof(unsigned long) == 4它们是不同的类型。因此,它可能不值得。