勿以善小而不为

     好几天前,就看过《C++ Coding Standards》的第一章了,一直想写点东西,可是一直觉得没有将这章内容写下来的必要,因此一直拖着。直到昨天,一件小事深深触动了我。
     昨天看《effecitive c++》的时候,遇到书上的一个例子,觉得挺有意思的,就想着试试。我一直有个习惯,总是喜欢自己亲自将代码写一遍,而不是从书上copy完事。昨天也是如此,当我写好代码以后,编译,出错,出错信息:error C2533: 'StringTe::{ctor}' : constructors not allowed a return type!真莫名其妙,我有点迷糊了,我的构造函数哪有返回值啊?但我相信,应该是我程序的问题,细细看来,才发现,我的类声明完以后,少打了个";",就这么一个小小的分号差点害得我六神无主。看来平时做事,每件事情都要认真去完成,无论大小,无论轻重。
     闲话就说到这里吧,进入正题。所谓正题,也是一个很浅显的题目:使用最高的编译级别对代码进行清洁编译。
     何谓清洁编译?清洁编译就是编译时不提示任何错误信息和警告信息。在我们对程序进行编译时,应该时刻都把警告信息放在心上。编译时,应该采用最高警告级别进行编译(在VC中是W4,默认为W3);而一旦出现警告信息,应该试图理解警告信息,并修改代码消除警告信息,而不应该忽视这些警告信息,通过降低警告级别消除他们,这会给我们的软件留下隐患。
     下面我们通过几个例子来说明编译时经常遇到的一些警告信息:
     例一:第三方头文件
      由于我们无法获得第三方类库的源代码,因此当遇到由第三方头文件而抛出的警告信息时,我们无法通过修过代码来消除警告信息。但是为了获得清洁编译,我们可以将第三方文件包装在另一个头文件中,而将在该头文件中关闭掉相应的警告信息,示例如下所示(下面代码中的语法依编译器不同而不同):

// File: myproj/my_lambda.h -- wraps Boost's lambda.hpp
#pragma warning(push)     // disable for this header only
 #pragma warning(disable:4512)
 #pragma warning(disable:
4180)
 #include 
<boost/lambda/lambda.hpp>
#pragma warning(pop)      
// restore original warning level

     例二:函数参数未使用
     遇到此类编译警告信息时,首先确保这个参数是否是无用的参数。如果是你为了以后扩展所留的占位符,或者是函数签名标准必须的参数,就删除掉函数参数的名字。

// warning: "unused parameter 'localityHint'"
pointer allocate( size_type numObjects, const void *localityHint = 0 ) {
  
return static_cast<pointer>( mallocShared( numObjects * sizeof(T) ) );
}

// new version: eliminates warning
pointer allocate( size_type numObjects, const void * /* localityHint */ = 0 ) {
  
return static_cast<pointer>( mallocShared( numObjects * sizeof(T) ));
}

     例三:变量已经定义了但从未使用过
      首先确保该变量确实不需要被使用,然后将该变量作为表达式插入代码中消除编译警告信息。

// warning: "variable 'lock' is defined but never used"
void Fun() {
 Lock 
lock;

 
// …

}

// new version: probably eliminates warning
void Fun() {
 Lock 
lock;
 
lock;

 
// …

}

     例四:使用变量前没有被初始化
     如果变量没有初始化,就初始化变量。具体做法参见《effective C++》第二版的Item12,Item13或是第三版的Item4。
     例五:缺少return语句
     很多时候编译器都需要为函数的所有控制流编写return语句,即使你认为函数根本就不可能到达那里。不过这也未必是坏事,而你也不必为此做很多事,只需要简单的加个return语句就可以了。

// warning: missing "return"
int Fun( Color c ) {
 
switch( c ) {
 
case Red:   return 2;
 
case Green: return 0;
 
case Blue:
 
case Black: return 1;
 }
}

// new version: eliminates warning
int Fun( Color c ) {
 
switch( c ) {
 
case Red:   return 2;
 
case Green: return 0;
 
case Blue:
 
case Black: return 1;
 
default:    assert( !"should never get here!" );   // !"string" evaluates to false
             return -1;
 }
}

     虽然,对于大多数警告信息我们都必须认真对待,但同时我们也应该看到,编译器有时也会产生一些很无聊的警告信息,甚至是一些虚假的警告信息,当遇到这种警告信息时,我们唯一能做的只能是禁止掉这些警告信息。
     终于为这一章做了个总结,可以开始看第二章的内容了。刚才又看了看《effective c++》第二版,才发现它的Item48说的也是同样的问题,看来编译器的警告信息确实值得我们认真对待。

posted @ 2005-09-07 15:37  Articles about .NET  阅读(539)  评论(0编辑  收藏  举报