Program Verification Systems 公司(针对 C 和 C++ 的静态代码分析工具 PVS-Studio 就是该公司的产品)发布了一份编程错误列表,有些错误是从Chromium、TortoiseSVN、Apache HTTP Server 和MySQL 等流行的开源项目中发现的。
这份列表维护的编码错误有150 多类,有的是严重的逻辑错误,有的是性能相关的问题,还有一些危害并不是很大。
下面是选自该列表的一些错误类型,示例代码都来自真实项目。
V502 ——或许‘?:’运算符的工作方式和想象中并不相同。该运算符的优先级比很多运算符都要低。
MongoDB:
string sysInfo() { .... stringstream ss; .... ss << (sizeof(char *) == 8) ? " 64bit" : " 32bit"; .... }
这是一个很好的例子。这段代码打印的是 0 或 1,而非“32bit”或“64bit”。
V511 ——在如下表达式中,sizeof 运算符返回的是指针的大小,而非数组的大小。
Chromium:
uint8 salt_[LINK_SALT_LENGTH]; VisitedLinkMaster::TableBuilder::TableBuilder( VisitedLinkMaster* master, const uint8 salt[LINK_SALT_LENGTH]) : master_(master), success_(true) { fingerprints_.reserve(4096); memcpy(salt_, salt, sizeof(salt)); }
“salt”对象就是一个指针。方括号中的值 LINK_SALT_LENGTH 向程序员表明,他们正在使用的是一个包含 LINK_SALT_LENGTH 个元素的数组。但传递给函数的并不是数组——只是个指针。因此,表达式 sizeof(salt) 返回的值是 4 或 8(32 位或者 64 位系统上指针的大小)。
到目前为止,这个列表上列出的、出现于各种开源项目的错误,很多可能已经修复。因为任何程序员都难免出错,所以使用一个或多个静态代码分析工具处理一下源代码是个不错的建议。Wikipedia 上有一个页面,列出了很多针对不同语言的静态代码分析工具。
参考英文原文: An Errors List Underscores the Need for Static Code Analysis
评论