责备别人之前先检查自己的代码
开发者——我们全部——经常不愿相信自己的代码出了问题。这不像会发生的事情,肯定是编译器出了问题。
然而实际上由于编译器、解释器、操作系统、应用服务器、数据库、内存管理器或者其它系统部件的bug导致代码出问题的情况实在是太少见了。是的,它们确实有bug存在,但是比我们愿意相信的要少见得多。
我遇到过一次真正的编译器问题,在优化掉循环变量时,但是我更多次是在假想编译器或者操作系统有bug。在这个过程中我浪费了很多自己的、支持的和管理的时间,每次等到最后发现时我自己的错误时,只觉得自己有点愚蠢。
如果工具在技术工作中广泛使用过、成熟了,那么就没有多少理由去怀疑它们的质量。当然,如果一个工具只是早期发布版本,或者在全世界范围内只有很少的人用过,或者是在一个很罕见的地方下载的,或者是开源软件的0.1版本,那么就有充足的理由去怀疑这个软件。(同样地,商业软件的alph版本也可以被怀疑。
考虑到编译器的bug是多少罕见,把要用来证明编译器出错的时间和精力花在在自己的代码中找错误会好得多。所有常用的调试工具都适用,隔离问题,查出调用,围之测试;检查调用转换、共享库和版本号;告诉其他人;检查堆栈错误和变量类型不符;在不同的机器上、不同的构建配置后,如debug和release,尝试运行该代码。
怀疑自己的设想,也怀疑他人的设想。不同的供应商提供的工具可能在构建时就有不同的假设,即便是同一个供应商的不同订单也可能这样。
作为我的个人准则,如果有一个不能查明的bug,我会开始想可能是编译器在原因,接下来开始找堆栈错误。如果增加跟踪代码让问题左躲右闪,就特别要这样了。
多线程的问题是另一个让人头疼、会让人向机器吼叫的问题。当一个系统是多线程的时候,对简单代码的青睐就会成倍增加。这些没有一致性的bug没法依赖调试和单元测试找出,所以简单的设计才是王道。
因而,当你急着想责备编译器的时侯,记住夏洛克·福尔摩斯的忠告:“一旦你排除了所有的不可能,剩下的无论看起来无何不可思议,也一定是真相”;相比起怪探德克的“一旦你排除了所有看起来不可能的,剩下的无论多么不可能,也一定是真相”,我更喜欢它。
原文:Check Your Code First before Looking to Blame Others by Allan Kelly