重构C ++代码以使用前向声明

时间:2010-02-19 16:32:08

标签: c++ compiler-construction refactoring forward-declaration

我有一个很长的代码库已经存在了一段时间,我试图通过重构来整理它。我想做的一件事就是找到我可以转发声明成员的所有标题,而不是包含整个头文件。

这是一个相当费力的过程,我正在寻找一种工具,可以帮助我找出哪些标题包含可以向前声明的成员。

是否有编译器设置可能会发出警告或建议以下代码可以使用前向声明?我正在使用以下编译器icc,gcc,sun studio和HP的aCC

是否有可以执行相同工作的独立工具?

#include "Foo.h"
...//more includes

class Bar {
.......
private:
    Foo* m_foo;
};

3 个答案:

答案 0 :(得分:4)

任何涉及C ++精确分析的内容都需要一个完整的C ++前端(否则你不会得到答案,或者它们会出错,而且当你有“大”的应用程序时,它会很糟糕)。这里没有很多实际答案。

已经提到GCCXML是一个GCC派生的包,所以它有必要的C ++前端。它产生XML,因此它将产生大量输出,你必须重新读回来形成另一个答案中建议的“内存数据结构”。不幸的是,GCCXML已经构建了内存数据结构,然后将其导出为XML,并迫使您再次构建它。当然,你可以使用GCC来构建内存数据结构,但是你必须破解GCC才能成为你想要的东西,并且真的,真的想要成为一个编译器。这意味着你将在你的手上进行一场战斗,将其弯曲到你的意愿(并解释为什么存在GCCXML:大多数人不希望那场斗争)。

未提及的是Edison Design Group C ++(EDG)前端,它直接在内存数据结构中构建。这是一个前端;你必须自己做所有的分析工作,但你的任务可能很简单,所以这并不难。

我知道的最后一个解决方案是我的:C++ FrontEnd for DMS。 DMS是构建程序分析的基础,它的C ++ FrontEnd是C ++的完整前端(例如,GCC和Edison前端所做的一切:解析,树构建,名称/类型解析)。而且,您必须通过遍历DMS生成的“内存”数据结构,对GCCXML和EDG的编码方式进行特殊编码。

真正不同的是,DMS可用于通过更新内存数据结构中的源代码来实际修改源代码,并从这些内存结构中重新生成可编译代码,包括原始注释。

答案 1 :(得分:3)

我不确定你会发现任何开箱即用的东西,但有一种选择是使用Python和pygccxml包写一个脚本,它可以进行一些分析。您。

基本上你会使用pygccxml来构建你的源代码的内存图,然后用它来查询你的类和函数,找出他们实际需要包含什么才能运行。

例如,您可以询问每个类,给我指定类型的成员:然后,对于每个指针类型,如果在接口中使用了类的实例(非指针),则可以解决这个问题。如果没有,你可以将其标记为前瞻性声明的候选人。

缺点是脚本需要一些时间才能正确,所以成本可能超过好处,但至少这将是一个有趣的练习。你可以将代码发布到Github,如果你有一些有用的东西,也许其他人会发现它有用。

答案 2 :(得分:3)

你可以做的是用-MM调用gcc。这将生成Make可以读取的依赖文件。您可以解析它们(使用perl或其他东西)来确定哪些包含是必需的,哪些可以用前向声明替换。而不是使用它们。