有覆盖变量作用域的代码度量标准吗?

8
在试图了解一些遗留的C++和C#代码维护难度以及引入错误的风险时,有人建议测量变量作用域的广度或狭窄程度可能会很有用。 该代码使用了许多全局变量或广泛作用域的变量,而本地变量则更好。 常见情况是发现这些变量在声明它们的几个作用域级别之后,被用于2或3行代码。
我知道静态代码分析工具通常试图量化耦合和内聚性,但是否有更专门测量变量/数据范围的方法?

3
我认为这是一个很好的衡量想法。 - SpaceTrucker
3个回答

2
是的,这是静态分析的标准技术之一,被称为变量存活性分析。在这本书中,介绍了如何进行这样的分析。
根据维基百科文章的解释:
在编译器理论中,变量存活性分析(或简称存活性分析)是编译器执行的一种经典数据流分析,用于计算每个程序点可能在其下一次写入之前潜在读取的变量,即在每个程序点退出时仍然存在的变量。
简单来说:如果一个变量保存着未来可能需要使用的值,那么该变量就是“活跃”的。

“将来可能需要”并不一定意味着“将来会使用”。简单的例子:C风格的for循环int i; for (i=0; i<10; ++i) meow(i);在此循环之后,i的值为10,这个值可能会被需要。然而,在大多数情况下,它是不需要/使用的。编译器会认为它是“活动的”,但如果我正确理解karm的话,他希望得到一个提示/警告,即i的作用域应该限制在for循环中:for (int i = 0; i<10; ++i) meow(i); - Arne Mertz
1
@ArneMertz:也许"活性分析"不是我所想的正确术语,但既然它基于数据流分析,我相信在你的例子中,只要在此时和第一个非条件写入i或i作用域结束之间没有从i中读取数据,则i将被评估为"死亡"。"可能需要"考虑(分析器所能做到的最好)变量的整个作用域,而不仅仅是在评估其活性的程序点之前的代码。 - Steve Jessop
...所以例如,如果循环后的下一条语句是puts("foo");,并且i已经失效,那么优化器知道它不需要在调用之间保留i的值,并且可能会因此节省一些指令和/或堆栈空间。这和寄存器分配是我最熟悉的活跃度用途,我看到gefei的观点认为它对这个问题也很有用。在您的示例中,并假设它在循环后没有使用,i仅在循环内部处于活跃状态(不在之前也不在之后),这足以引发所需的提示以减少其范围。 - Steve Jessop
话虽如此,以另一个例子 int i = 0; ...; for(;i < 10; ++i)(其中...不使用i)需要更多的活性定义才能得出结论,即i可以缩小范围。您还必须检测i的初始化可以尽可能地延迟到第一次读取它时(当然要考虑导致条件读取的分支,但是这个例子没有这些)。DFA通常也会这样做,但我不知道它是否被称为“活性”或其他名称。 - Steve Jessop

0

你可以尝试CppDepend和它的CQLinq代码查询语言,来检测仅被单个方法或类使用的全局变量。

from f in Fields where f.IsGlobal && f.MethodsUsingMe.Count()==1 select f

0

我将集中讨论OO语言(Java、C#、C++)中的局部变量。我可以想到一些关于局部变量作用域的措施。

局部变量作用域大小
是局部变量可访问的语句数量。这个值不应该太大,因为这表示方法过长。然而,方法语句计数可能更适合用来衡量。

可访问局部变量计数
是每个方法语句可访问的局部变量数量。这个值不应该超过3,因为这会使在表达式中选择要使用的局部变量更加困难。

局部变量使用密度
是访问局部变量的语句占所有可访问局部变量语句的百分比。低值表示该方法不太连贯。

局部变量的连贯修改计数
是同一块内局部变量修改的次数。这表示多个局部变量属于同一组。因此,它们应该形成自己的对象,从而增加连贯性。


保持可访问的本地变量数量不超过3个将会很棘手,你提到的这三种语言都有标准的方法/函数,其参数超过3个,因此无法实现该限制。在C++中,显式参数是一个本地变量,我不确定其他语言是否也是如此,但是为了选择在给定表达式中应该使用哪个名称,参数也可以视为本地变量。当然,这是一个高尚的目标,如果要求审查设计,您可能会标记这些标准函数为危险的。 - Steve Jessop
@SteveJessop 我并不是想让它们成为严格的限制条件。但我必须承认,我没有考虑到参数。所以我想5可能是一个更合适的值。 - SpaceTrucker
我完全同意这个观点,值得我们牢记。在实践中,我会看一些我喜欢的函数和我讨厌的函数,并尝试从中分辨出一个指导价值。由于有时你愿意让代码变得有点复杂,而其他时候你想保持一切非常简单,因此对于不同类型的组件可能会有所不同。 - Steve Jessop

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