将C++源代码中的内联方法移到.cpp源文件中的工具?

13

我们应用程序的源代码有数十万行、数千个文件,而且在某些地方非常老旧 - 应用程序最初是在1995或1996年编写的。过去几年中,我的团队大大提高了源代码的质量,但仍有一个特别让我烦恼的问题:很多类在其头文件中完全定义了许多方法。

对于某些情况下在头文件中声明内联方法,我没有任何问题 - 比如结构体的构造函数、一些简单的方法,在这种情况下内联可以明显加速(我们有一些像这样的数学函数),等等。但是在没有明显原因的情况下大量使用内联方法:

  • 混乱
  • 使查找方法的实现变得困难(尤其是在一棵类树中搜索虚函数,结果发现其中一个类在头文件中声明了其版本...)
  • 可能会增加编译后的代码大小
  • 可能会导致链接器出现问题,我们的链接器对于大型代码库来说是臭名昭著的(尽管近年来已经好了很多,但仍不完美)

最后一个原因可能现在正在给我们带来问题,这是一个好的理由去检查代码库并将大多数定义移到源文件中。

我们的代码库非常巨大。 是否有自动化工具可以为我们完成(大部分)任务?

备注:

  • 我们使用Embarcadero RAD Studio 2010。换句话说,C++方言包括VCL和其他扩展等。
  • 一些头文件是独立的,但大多数都与相应的 .cpp 文件配对,就像通常的做法一样。除了扩展名外,文件名相同,例如,如果在 X.h 中定义了方法,则可以将它们移动到 X.cpp 中。这也意味着工具不必处理整个项目-它可能只需解析单独的.cpp/.h 文件对、忽略包含等,只要能可靠地识别类声明中定义了方法体并将其移动即可。

  • 12
    让一位实习生来做。 - Tomas Andrle
    1
    @Zuljin:嗯,可能吧...但是没有适用的答案!(VS插件没有显示在他们的网站上进行批量更改的迹象,而所有评论和答案中得票最高的东西都是说“哦,你可以轻松地创建一个脚本...”我不认为“容易”和“解析C ++”通常会联系在一起!) - David
    5
    你认为1995年的代码已经过时了。真可爱 :-) - Martin York
    1
    @TheBuzzSaw:如果没有非常强大的 C++ 操作技术,使这个想法实现起来就不会很有趣。即使有好的技术,也很难做到。 - Ira Baxter
    1
    @IraBaxter 喔,你把它夸大了。如果你只是想将内联函数从头文件移动到cpp文件中,你只需要一些字符串操作基础知识。你不需要把整个LLVM套件都带进来。 - TheBuzzSaw
    显示剩余7条评论
    4个回答

    7

    +1:不知道这个工具 :) - neuro
    +1,以前从未听说过。快速浏览后,看起来是这种工具非常有用! - David
    阅读了常见问题解答后,我联系了作者。该工具需要在.lzz文件中编写代码,Lazy C++会解析并将其拆分为CPP和H文件。我认为将我们的代码合并到单个文件中,只是为了让工具再次拆分它们可能需要同样多的工作... :) 谢谢您的建议,这是一个有趣的工具。 - David

    2
    如果代码能够正常工作,那么我反对进行任何重大的自动化重写。修复它可能需要大量的工作。 随着时间的推移进行小的迭代改进是更好的技术,因为您将能够测试每个变化并添加单元测试。无论如何,您关于无法找到代码的主要抱怨不是真正的问题,已经有工具可以索引您的代码库,因此您的编辑器将跳转到正确的函数定义,而无需搜索它。看看您的编辑器是否有ctags或类似工具。
    - 杂乱无序 - 主观的 - 使查找方法的实现变得困难(尤其是在类树中搜索虚拟函数,只发现一个类在头文件中声明了版本...) - 已经有可用于查找函数的工具。`ctags`将生成一个允许您从任何良好的编辑器(vim/emacs)直接跳转到该函数的文件。我相信您的编辑器如果不是这些编辑器之一,也会有等效的工具。 - 可能会增加编译代码大小 - 不太可能。编译器将基于内部指标选择是否内联,而不是源代码中是否标记为内联。 - 可能会导致我们的链接器出现问题,对于大型代码库来说,链接器非常不稳定。公平地说,过去几年它已经变得更好了,但它并不完美。 - 不太可能。如果您的链接器有缺陷,则无论函数在哪里定义都没有关系,因为这与它们是否被内联无关。

    我会说“修复它需要大量的工作”,甚至可以说“修复它将涉及大量的工作”。 - Sjoerd
    谢谢Loki。我不想进行“重写” - 我想保持逻辑代码不变,只是将其位置移动。我知道这并不像那么简单,但是... :) 我预计可能会运行一些工具并手动审核其更改,并且我非常了解尽管存在其大小的代码库,所以我对此感到非常自信。关于其他方面的问题,这个SO问题可能会让你感兴趣。 - David

    1

    您需要解决以下问题:

    • 如何理想地重新组合源文件和头文件
    • 如何自动化代码修改以实现此目的

    在这两种情况下,您需要一个强大的C++解析器,具有完整的名称解析功能,以准确确定依赖关系。

    然后,您需要可靠地修改C++源代码的机制。

    我们的DMS软件重构工具包及其C++前端可以用于此。DMS已被用于大规模的C++代码重构;请参阅http://www.semdesigns.com/Company/Publications/并查找第一篇论文“Case Study: Re-engineering C++ Component Models Via Automatic Program Transformation”。(您可以从那里下载旧版本的论文,但发表的版本更好)。据我所知,DMS是唯一一个应用于大规模转换C++的工具。

    这个SO上有关重新组织代码的讨论 解决了直接分组的问题。


    1

    XE2 包含了一个新的静态分析器。试用一下 C++Builder 的新版本可能是值得的。


    谢谢David!我实际上有一份C++Builder XE2 Pro的副本,所以我会尝试使用它。(尽管工作仍在使用2010版 - 我们正在等待64位升级 - 但我尽量保持最新,因此有了自己的副本。)我之前只尝试过2010版中可用的重构,但它们并不是很可靠。 - David

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