我研究过数百个因“拷贝-粘贴”导致的错误。可以肯定的是,程序员常常会在一大段代码的最后一段里犯错。好像还没有任何编程书讨论过这种现象,因此我决定自己写点什么。我称之为“末行效应”。 我叫Andrey Karpov,我的工作有点不寻常:我借助静态分析工具研究各种应用程序代码,并描述从中找到的错误或者缺陷。我这么做既有实际效益也因为工作需要。使用的方法正是基于我们公司所推广的PVS-Studio和CppCat工具的原理。套路很简单:找bug,然后写文章分析bug,文章吸引到潜在用户的注意,接着就是收益。但今天这篇文章不是介绍这些工具的。 在分析各种软件项目的过程中,我把找到的bug以及相关代码存入一个特殊的数据库。顺便说一下,有兴趣的话各位可以看一看这个数据库。我们把它转换成网页格式并上传到了公司网站的“Detected errors”栏下。 这个数据库独一无二!目前它收录了1500块问题代码片,正等着程序员们去研究,从中总结出特定规律。为将来的研究,手册和文章奠定一个基础。 我还没认真地分析过目前搜集到的材料。但是过程中我发现有一个明显的模式反复出现,决定深入研究一下。你大概看到了,文中我反复使用短语“注意最后一行”。在我看来,这一定有某种规律。 末行效应编程的时候,程序员常常需要写一系列相似的结构。逐行敲键盘输入无聊且低效。这就是为什么他们会使用奥义-“拷贝-粘贴”大法:一段代码被拷贝粘贴几次,然后修改。谁都知道这样做的坏处:你很容易在粘贴后忘记修改某些内容最后滋生出问题。不幸的是,常常找不到比这更好的方法。 那么我发现了什么规律呢?我发现错误常常发生在最后的一块粘贴代码里。 下面是一个简短的例子:
注意这一行:”z += other.y;”。程序员忘记把‘y’替换成‘z’了。 也许你以为这是个假设的例子,然后它其实来自一个真实的应用程序。接下来,我会让你相信这是高频常见的一种错误。程序员们经常在一连串相似操作的结尾犯这种错误。 我听说攀岩者常常在最后的几十米中滑落下来。并不是因为他们累了,而正是由于他们对即将到达的终点过于兴奋,他们想象着成功后的喜悦,变得疏忽大意,最后失足。我猜想程序员们也是这样的。 接下来看一组数据。 研究了数据库后,我分离出了84个代码段由“拷贝-粘贴”大法生成。其中41段中错误发生在中间的某些粘贴块。比如:
“THREADS=”字符串的长度是8个字符,而非6。 另外的43段代码中,错误发生在最后的粘贴块。 当然,43比41大不了多少。但是请注意,一段程序中,可能有很多类似的代码块,因此错误可能发生在第一,第二,第五甚至第十块中。因此在其他代码块中我们有一个相对均匀的分布,而最后一块却存在一个峰值。 平均而言,相似代码块总数为5。 于是前面4个代码块中均匀分布了41处错误,平均每块代码有10个错误。 然而最后一块代码中有43个错误! 下面的分布概图凸显出这个现象: 因此我们可以总结出一个规律: 在最末的粘贴代码块中出错的概率是其他代码块的4倍。 这个规律可能并没有普适性。它只是个有趣的发现,其实际效用在于:提醒在你写最后一块的时候保持警觉。 实例:下面我要证明这并不是我的胡思乱想而是有真实的趋势的。请看下面的实例。 当然,我不会列出所有例子,仅列举简单而有代表性的。 Source Engine SDK
最后一行应该是SetW()。 |