是否有一款可用的C++重构工具?

169

有没有人知道一个完整的C++重构工具,可以可靠地处理大型代码库(约10万行)?

在过去的几年里,我尝试了所有能找到的工具:SlickEdit、Eclipse CDT等等。但它们都无法使用。

总结: 我花时间评估了"Visual Assist X"和"Refactor for C++"。两者都有一些令人印象深刻的功能,但都远非完美。提取大块代码通常需要手动修改,因此效果不佳。

"Visual Assist X"具有很好的功能,例如更完整的自动完成等。但在某些点上会导致太多闪烁并明显变慢。

因此,我的意见是:"否,目前没有用于生产的C++重构工具"

更新于2015年3月 根据hdoghmens今天的回复,我尝试了Resharper for C++。 他的链接https://www.jetbrains.com/resharper/没有提到C++。但我发现了Resharper C++,它在一年多前在这里宣布:

https://www.jetbrains.com/resharper/features/cpp.html

我尝试使用20MB的代码库在VC2010上进行了尝试。

测试1:提取方法: 结果出现了Resharper异常。没有更改源代码。

测试2:使用不同的源代码进行方法提取: 运行正常。

测试3:更改提取函数的签名: 导致C++代码错误。

bool myclass::do_work123(<unknown long Color>int& Filled*&, long, int&)

也许这就是为什么C++没有出现在主页上的原因。
在我看来,对于这个问题的答案仍然是“不”。

12
已将此标记为“收藏”。C++的问题在于其非常复杂、上下文敏感的语法。如果没有解析完整的源代码,你无法确定标识符的含义。 - DevSolar
参见:https://dev59.com/60XRa4cB1Zd3GeqPtaW7,但它没有太多提供。 - dmckee --- ex-moderator kitten
4
Eclipse实际上运行得相当不错,你只需要通过编辑eclipse.ini文件来允许它使用更多内存。 - n0rd
3
如果您仍在监控C++的重构工具,请注意我们JetBrains目前正在开发支持C ++ ReSharper和单独跨平台C ++ IDE。 - Jura Gorohovsky
1
@RED SOFT ADAIR,你很有名哦。看看这个链接:https://youtu.be/RT46MpK39rQ?t=1611 - user6600549
让我们看看未来可能会带来什么 :-) - Xan-Kun Clark-Davis
19个回答

42

Visual Assist和Visual Studio使处理大型代码库更加容易。Visual Assist能够很好地跟踪类或成员的使用情况,并且在重命名时比搜索和替换功能更有效,不会出现误报情况。


38

8
很不幸,Refactor for C++ 在处理大型代码库时效果非常差(如果有的话)。 - Daniel Rose
1
重构 C++ 和大型代码库会发生什么具体的事情? - Ira Baxter
2
@IraBaxter 它就是坏了。重构选项要么不显示,要么无法完成。出现奇怪的错误消息或根本没有任何消息。 - Daniel Rose
4
即使对于小型代码库,使用C++的重构工具也不能很好地运行,它已经损坏且完全无法使用。 - kovarex
1
VA似乎完全不理解C++。 - Nils
3
@Nils: 你能举个具体例子说明它不理解什么吗? - Ira Baxter

27
我认为在未来几年内,clang将显着改变现有C++重构工具的格局。它是一个开源的、模块化的编译器,可以公开API用于解析和语义分析C++代码。IDE和其他工具可以使用这个API,而不必费力地编写自己的解析器和语义分析器。 Google已经使用clang制作了大规模重构工具

3
有没有一些谷歌之外的凡人也能使用的结果? - Jan Hudec
1
@JanHudec:请查看此处链接的教程:http://comments.gmane.org/gmane.comp.compilers.clang.devel/23203 - HighCommander4

17

Mozilla有自己的重构工具,名为Pork (Wiki, Developer Wiki)。这是Pork背后开发者的博客。据我所知,Pork已经成功地用于Mozilla的重构中。

如果你来自*nix领域,Pork应该会有所帮助;对于Visual Studio,我也推荐使用Visual Assist。


9
我们的DMS Software Reengineering Toolkit是一个转换引擎,旨在对大量代码进行复杂的转换,包括C++。它已被用于对数百万行代码系统进行可靠的更改。它通过使用编译器精确的语言分析器和变换器来操作。 它具有完整的C++解析器,带有名称和类型分辨率,构建代码的AST,可以应用面向过程或源到源的变换(具有C++表面语法),以修订这些树,并产生保留注释的可编译输出。(编辑:7/1/2011: 现在可以实现C++1X,只要我们理解标准 :)) 它已被用于大规模的软件重构项目,包括C++组件重新架构和语言之间的100%全自动翻译。 您可以在网站上阅读相关信息。 DMS也用于构建任意源代码分析工具。例如克隆检测、测试覆盖率、智能差异(比较源代码结构和抽象编辑操作,而不是插入和删除简单的行),等等。
目前它不是一个交互式重构工具。我们认为,要做好大多数重构,您需要进行深入的控制和数据流分析。DMS具有支持此功能的通用机制,并且在此时已实现了C、COBOL和Java,下一步是C ++。这是一项艰巨的工作。在解决这种问题之前,您不会看到任何人提供大量的严肃C ++重构工具。首先,您需要完整的C ++解析器:-}
编辑7/5/2011:看起来我们将尝试交互式版本。我们赢得了能源部第I阶段SBIR,以调查如何做到这一点。请参见http://science.energy.gov/sbir/awards-and-general-stats/fy-2011/phase-i-by-state/?p=1#tx(在“德克萨斯州”下查找Semantic Designs)。不要指望很快就会有结果;这只是一个三阶段多年计划的开始,以获得工具。

编辑于2011年8月11日:第一个进展...我们现在处理所有的C++0x和OpenMP指令。

编辑于2012年1月4日:对C++代码进行了完整的控制流分析。

编辑于2014年9月15日:现在已经很好地掌握了C++14前端解析器/转换引擎。甚至此时重命名也相当可靠 :-}


在您的下载页面http://www.semanticdesigns.com/Products/RegisterEval.html上似乎没有评估此工具的链接。目前是否有VS2010或VS2008的试用版本和定价信息可用? - SmacL
DMS能够转换VS2008/VS2010,但不能作为交互式工具,并且在预处理器指令方面存在一些限制。(好消息是,我们认为我们解决了这些主要问题,并将在第二阶段的研发计划中应用它们)。 - Ira Baxter
谢谢您的反馈,但它似乎不是我需要的工具类型。我不需要交互式工具,只需要能够对大型代码库执行相对简单的转换而不会花费太多代价的工具,例如更改调用所需参数的数量,将指针参数更改为引用。VisualAssist已经很接近了,只需要再进一步。 - SmacL
对于我过去需要进行的简单转换,我编写了临时程序,基于广泛的测试套件来验证结果,这些程序一直运行良好。例如,将文字替换为读取资源的调用。是的,有许多边缘情况可能导致转换失败,但仍然比手动操作要好。我在整个番茄论坛上详细介绍了这个问题:http://www.wholetomato.com/forum/topic.asp?TOPIC_ID=9962 - SmacL
3
DMS的目的是实现编码和无误差地应用代码转换,无论是“重构”还是其他形式。是的,这很难,而且我们还没有达到那个水平。我认为,在所有我见过的C++工具中,我们更接近实现这个目标,我们的工具基础没有问题。剩下的问题涉及预处理器、代码规模以及努力编写C ++语义以允许这样的转换。我将第一个承认,这是一个庞大的项目。 - Ira Baxter
显示剩余7条评论

8
如果你使用emacs,可以尝试Xrefactory。它支持方法提取、重命名类/函数/变量以及插入/删除/移动参数。它还有非常好/快的代码完成引擎。

6

目前我无法推荐任何C++重构工具,尤其是对于超过100k行的大型代码库。就像提问者一样,我一直希望这种情况会改变,希望有一天会出现好的工具。但我担心,在我们看到真正好用的工具之前,语言本身可能需要发生重大变化。

顺便问一下,SlickEdit是否已经放弃了其重构功能?


语言确实发生了重大变化,随着C++2011标准的发布。额外的复杂性使问题变得更加困难,而不是更容易,因为所有用户都希望拥有所有先进的语言功能和重构能力 :-{ - Ira Baxter
2
最近阅读了关于Slickedit的能力,它似乎通过启发式方法确定与名称使用相对应的定义。它不执行“正确”的C++名称查找。这意味着您不能信任其转换是正确的。如果您不介意检查其工作,则可能适合您。在真正大型的软件包中,这可能不是很好。这是我的观点。 - Ira Baxter

4
如果你使用emacs并且还没有尝试过,我建议尝试一下rtags(也有可用于vim的)。它是一个基于clang的客户端/服务器应用程序,可索引C/C++代码,并具有以下功能:
  • 跳转到定义/声明
  • 查找所有引用,跳转到上一个/下一个
  • 重命名符号
  • 与clang的“fixits”集成
在观看了这个演讲介绍了rtags(和emacs)之后,我决定尝试一下。

(我不得不说,在QtCreator不能正确地重命名某些符号之后,我才走到了这一步,这对我现在使用这个伟大的IDE来说是一个停滞不前的问题)

除了rtags支持的内容外,我还需要一些额外的不错的功能,包括:
  • 创建函数定义/原型
  • 提取函数
  • 创建getter/setter方法
对于这些,我推荐使用emacs的semantic-refactor包(不确定是否有vim的替代品)。
总的来说,基于clang的工具看起来非常有前途。如果你对用于C++重构的clang工具的更多信息感兴趣,包括针对大型代码库的项目,那么Chandler Carruth的一些精彩的演讲会提供更多的信息。

3

这个问题与C++模板有关。截至2019年,我不知道有任何支持C++模板的重构工具。我已经尝试过VS2019、VisualAssist、Clion和QtCreator。

考虑以下示例:

#include <iostream>

struct foo { void print() {} };
struct bar { void print() {} };

template <typename T>
void call_print(T&& v) { v.print(); }

void print() {}

int main()
{
    call_print(foo{});
    call_print(bar{});
    return 0;
}

如果我在 foo::print 上运行"重命名重构",那么由于它们是通过call_print函数模板实例化相关联的,所以bar::print也应该自动重命名。

3

DMS软件工程工具包可以实现这一点。它是一个代码转换引擎,专为大规模处理C++而设计。虽然我不知道输出结果有多优雅。


1
DMS已被用于自动化重构大量的C++代码。请参见Akers,R.,Baxter,I.,Mehlich,M.,Ellis,B.,Luecke,K.,案例研究:通过自动程序转换重新设计C++组件模型,Information&Software Technology 49(3):275-291 2007年。可从出版商处获取。 - Ira Baxter
不知道您所说的“优美输出”是什么意思。您从DMS获得的输出显然取决于您提供的内容和应用的转换。如果转换不涉及代码的某些部分,则该部分代码与一开始时一样优雅或不优雅。如果它确实涉及代码,则优雅程度取决于转换有多聪明,就像程序员手动更改一样。我认为这不是优雅的问题,而是结果的格式可以是“忠实度”打印(原始格式),也可以是自定义的漂亮打印样式。 - Ira Baxter

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