如何从复杂算法中提取活动代码路径

3
最近我被一个有趣的想法困扰着。
我想知道是否有一种(已知的)方法可以从一个复杂的算法中提取执行的源代码。我将尝试详细说明这个问题:
场景: 有一个复杂的算法,许多人已经在上面工作了很多年。该算法创建了一个复杂测量设备的测量描述。
算法的输入是一组大量的输入参数,我们称之为“配方”。基于这个配方,执行算法,并且配方决定了算法内部遵循哪些函数、循环和if-else结构。当算法完成后,一组计算出的测量参数将形成输出。通过这些输出测量参数,设备可以进行测量。
现在,有一个问题。由于算法随着时间的推移变得如此复杂和庞大,所以当您想要为配方添加新功能时,很难找到您在算法中的位置。基本上,一个人只想修改受其配方影响的函数和代码块,但他/她必须深入整个算法并分析代码,以查看哪些代码与他或她的配方相关,只有在此过程之后才能在正确的位置添加新功能。即使是简单的添加,人们也往往会在大量复杂的代码中迷失方向。
解决方案:提取活动代码路径? 我一直在思考这个问题,我认为如果有一种方法可以使用输入参数(配方)处理算法,并仅将活动函数和代码块提取到一组新的源文件或代码结构中,那将是很棒的。我实际上是在谈论提取真正的源代码。
当活动代码被提取并隔离时,这将导致一个子集的源代码,它只是原始源代码结构的一小部分,对于人们来说更容易分析、理解代码并进行修改。最终,更改可能会合并回算法的原始源代码,或者修改后的提取源代码也可以单独执行,就像是原始算法的“轻量版”。
额外信息: 我们正在讨论一个带有C和C++代码的算法,大约有200个文件和100K行代码。代码是使用自定义基于Visual Studio的构建环境编译和构建的。
所以...: 我真的不知道这个想法是天真愚蠢的,还是在适当的软件工程量下是可行的。我可以想象,在软件工程领域中可能有更多类似的情况,但我不知道。
我在软件工程方面有相当多的经验,但肯定不是设计大型复杂系统的水平。
我会感激任何形式的答案、建议或评论。
提前致谢!

你有源代码的访问权限吗?也许通过VS提供的代码覆盖工具,你可以实现这个。 - rpax
我想知道是否有一种(已知的)方法可以提取... - 很遗憾你坚持要使用已知的方法,否则我本来有几个建议。 - Tony Delroy
2个回答

1

其他反对者说你做不到这个。我不同意。

一个标准的静态分析是通过代码确定控制和数据流路径。有时这样的工具必须做出关于可能发生的事情的假设,因此这些分析往往是“保守”的,可以包括比真正的最小值更多的代码。但是消除不相关的代码听起来会帮助你。

此外,您可以提取特定程序输入的控制和数据流路径。然后,当提取算法不确定可能发生什么时,它可以检查特定输入会导致发生什么。这以提供有效输入为代价,提供了更精确的结果。

最后,使用测试覆盖工具,您可以相对容易地确定感兴趣的特定输入执行的代码,以及另一个输入执行的代码,对于不那么有趣的情况,计算集合差异。这给出了由有趣案例执行的代码,而不与不有趣的案例共同使用的代码。

我的公司构建编程分析工具(见我的个人简介)。我们对C++源代码进行静态分析,提取控制和数据流路径,并可以轻松地查看涉及的代码。我们还制作了C++测试覆盖工具,可以收集有趣和无趣的集合,并将差异叠加在源代码上展示给您。

Visual Studio已经具备了代码覆盖分析功能,包括将结果导出为XML文件的能力(参见此处)。周围有很多XML差异工具 - 也很容易编写。 - Tony Delroy

0

很抱歉,您尝试的方法在数学上是不可能的。问题在于这个

当算法完成时,一组计算出的测量参数将形成输出。

无法通过静态代码分析来确定。

您遇到的实质上是停机问题的一个变体,已经证明不存在一个可以确定传入它的算法是否会在有限时间内产生结果的算法/程序。


我不认为原帖作者将其限制在静态分析范围内。理论上,如果你被允许实际运行程序,这是可能的,但很可能非常困难,以至于最好还是费力地穿越困难而密集的代码... - SirGuy
1
valgrind --tool=callgrind - bobah
@bobah:这只会产生程序被测试的输入子集的调用图。 - datenwolf
@datenwolf - "这将仅产生程序被测试的输入子集的调用图" - 这正是问题所要求的。 - Tony Delroy

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