把if语句放在常量后面的原因是什么?

我正在查看一些C ++代码,用于我正在使用的硬件接口,并注意到大量的语句如下:

if ( NULL == pMsg ) return rv; 

我敢肯定,我听到有人说,把恒定放在首位是个好主意,但为什么呢? 是不是这样,如果你有一个大的声明,你可以很快看到你在比较什么,或者有更多的?

所以你不要把比较(==)和赋值(=)混合在一起。

如你所知,你不能指定一个常量。 如果你尝试,compliler会给你一个错误。

基本上,这是防守性的编程技巧之一。 保护你自己。

阻止你写作:

  if ( pMsg = NULL ) return rv; 

因为失误。 一个好的编译器会提醒你这个问题,所以大多数人不会使用“恒定优先”的方式,因为他们觉得很难阅读。

它停止单个=分配错误。

例如,

 if ( NULL = pMsg ) return rv; 

将不会编译,在哪里

 if ( pMsg = NULL) return rv; 

会编译并给你头痛

为了弄清楚我在一些评论中写的是什么,这里有一个不在 C ++代码中这样做的理由。

有人写,比如说,一个string类,并决定添加一个转换操作符const char*

 class BadString { public: BadString(const char* s) : mStr(s) { } operator const char*() const { return mStr.c_str(); } bool operator==(const BadString& s) { return mStr == s.mStr; } // Other stuff... private: std::string mStr; }; 

现在有人盲目地应用constant == variable “防御”编程模式:

 BadString s("foo"); if ("foo" == s) // Oops. This compares pointers and is never true. { // ... } 

海事组织是一个比意外分配更为阴险的问题,因为你无法从呼叫地点得知任何明显的错误。

当然,真正的教训是:

  1. 不要编写自己的string类。
  2. 避免隐式转换操作符,特别是在执行(1)时。

但是有时候你正在处理你无法控制的第三方API。 例如,在Windows COM编程中常见的_bstr_tstring类遭受这个缺陷。

当常量是第一个时,编译器会警告你,如果你不小心写=而不是==因为将一个值赋给一个常量是非法的。

他们说,“防止任务和比较的混合”。

在现实中,我认为这是无稽之谈:如果你是如此的严谨,以至于你不会忘记在左边不变,那么你肯定不会把'='和'=='混在一起,对吗? ;)

编译器输出警告是好的,但我们现实世界中的一些人不能将警告视为错误。 反转variables和常数的顺序意味着这个简单的滑动总是显示为一个错误,并防止编译。 你很快就习惯了这种模式,它所保护的bug是一个微妙的问题,一旦引入就很难find。

我忘记了这篇文章,但是引用的内容是这样的:“显然它更容易记住把常量放在首位,而不是记住使用==”;))