对于图1中的程序其中存在一个问题,那就是38行if语句中的判断条件,这一程序的结果是只有else语句中的程序会被执行。其中的错误在于,if语句中本应是“==”,但却被误写成了“=”,因而_p_ref中的prev_被斌值成了零,接着if语句判断其是否为true,由于零被当作是false所以永远只有else语句中的程序会被执行。

dll.c
00036: void dll_insert_before (dll_t *_p_dll, dll_node_t *_p_ref,
dll_node_t *_p_inserted)
00037: {
00038:     if (_p_ref->prev_ = 0) {
00039:         _p_dll->head_ = _p_inserted;
00040:         _p_ref->prev_ = _p_inserted;
00041:         _p_inserted->next_ = _p_ref;
00042:         _p_inserted->prev_ = 0;
00043:     }
00044:     else {
00045:         _p_ref->prev_->next_ = _p_inserted;
00046:         _p_inserted->prev_ = _p_ref->prev_;
00047:         _p_inserted->next_ = _p_ref;
00048:         _p_ref->prev_ = _p_inserted;
00049:     }
00050:     _p_dll->count_++;
00051: }
图1

类似这种错误有可能造成很大的问题,如何通过编程习惯去避免它呢?方法就是养成将常量放在“==”前面的习惯,如图2中的38行所示。一旦“==”被误写成了“=”的话,由于常量零是不能用做左值的,因此,编译器就能帮助发现这一失误。显然,当“==”两边的都是变量时,如果出现失误,还是不能被发现。

dll.c
00036: void dll_insert_before (dll_t *_p_dll, dll_node_t *_p_ref,
dll_node_t *_p_inserted)
00037: {
00038:     if (0 == _p_ref->prev_) {
00039:         _p_dll->head_ = _p_inserted;
00040:         _p_ref->prev_ = _p_inserted;
00041:         _p_inserted->next_ = _p_ref;
00042:         _p_inserted->prev_ = 0;
00043:     }
00044:     else {
00045:         _p_ref->prev_->next_ = _p_inserted;
00046:         _p_inserted->prev_ = _p_ref->prev_;
00047:         _p_inserted->next_ = _p_ref;
00048:         _p_ref->prev_ = _p_inserted;
00049:     }
00050:     _p_dll->count_++;
00051: }
图2

如果做进一步思考的话,能否通过禁止在if的判断条件语句使用“=”来彻底杜绝这类问题呢?当然,要做到这一步,这需要改变编译器的行为,进一步还得更改C/C++语言的规范,这是个不小的动作。在某些情况下为了简化程序书写,会故意在if的判断条件语句中使用“=”,但现在看来这种灵活性还是让我们付出了代价。这就是C/C++语言!并不严谨的语法带给了我们一定的灵活性,当然也给我们带来了“意外”。这类灵活性我们真的需要吗?除了if语句可以使用这一编程习惯,图3示例了另一种情形。

example.c
00054:     stack_size = (0 == stack_size) ? STACK_DEFAULT : stack_size;
图3