解开.h依赖

时间:2009-06-07 17:47:06

标签: c dependencies projects

如果你有一套.h文件已经成为经典'gordian结'的受害者,你会怎么做?#include one .h意味着你最终包括几乎所有的?预防显然是最好的药物,但是如果在供应商(!)运送库之前发生了这种情况,您会怎么做?

这是问题的扩展,这可能是更相关的问题 - 应该你甚至试图首先解开依赖关系?

4 个答案:

答案 0 :(得分:4)

我在已经拆分成许多库的C ++代码库上做到了这一点(这是一个好的开始)。

我不得不锻炼(或猜测)哪个库最依赖,这取决于代码库中的其他内容。然后我依次处理每个库。

我依次查看每个模块(* .cpp文件)并确保其自己的标头首先是#included并注释掉其余部分,然后我注释掉了该头文件中的所有#includes然后重新编译只是那个模块让编译器告诉我需要什么。我会取消评论似乎需要的第一个标题,并审核那个标题,并在必要时进行递归。有趣的是看到有多少标题最终不需要。

只需要名称(因为你有一个指针或引用),使用class name;struct name;,这称为前向声明,并避免#include头文件。

当你注释掉#includes时,编译器非常有助于告诉你依赖是什么(你需要使用所有编译器重新编译以保持可移植性)。

有时我不得不在库之间移动模块,这样就不会有任何一对或一组库相互依赖。

答案 1 :(得分:1)

如果有机会,您应该重构代码以减少太大的包含,但是假设您可以实现某种包内聚。如果您解开一些事情只是为了发现代码的每个用户都必须包含所有元素,最终结果是相同的。

另一种选择是使用#defines来打开和关闭部分。无论如何,对于现有的代码库,解决方案是转向封装内聚。

阅读:http://ivanov.files.wordpress.com/2007/02/sedpackages.pdf并研究与包装凝聚力相关的问题。

答案 2 :(得分:1)

我已经解开了几次这个结,并且在维护系统时尽可能地减少.h依赖性通常会有很大帮助。有很好的工具可以生成依赖树(我当时正在使用Klocwork)。

我发现的缺点是条件编译。有人可能会删除头文件,因为他们认为我们不需要它,但事实证明我们只是不需要它,因为VxWorks有一些搞砸的头文件......在Solaris(或任何合理的Posix系统)上你需要它它

答案 3 :(得分:0)

在大量精细组织的标题和包含所有内容的单个标题之间存在平衡。考虑标准C库;有一些像<stdio.h>这样的大标题,它声明了很多函数,但它们都与I / O有关。还有其他标题更多的是杂项 - 特别是<stdlib.h>

戈达德太空飞行中心的C指南值得追捕。

基本规则是每个标题应声明由适当的(通常很小的)源文件集提供的工具。设施和标题应该是独立的。也就是说,如果有人需要标头"something.h"中的代码,那么这应该是必须添加到编译中的唯一标头。如果"something.h"中需要的设施未在标头中声明,则必须包含相关标头。这可能意味着标题最终包括<stddef.h>,因为其中一个函数使用size_t,例如。

正如@quamrana指出的那样,你可以在适当时使用结构的前向声明(不是类,因为问题是标记C而不是C ++) - 这主要意味着当接口获取指针并且不需要知道大小时结构或任何成员。