2010-01-26 66 views
55

我一直在寻找一些例子下我的工作硬件接口++代码,发现大致如下大量的报表:将常量放在if语句之后的原因是什么?

if (NULL == pMsg) return rv; 

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

+4

+1一个非常好的问题标题。 – OregonGhost 2010-01-26 10:24:57

+1

很确定我已经看过这个问题不止一次,现在找不到它。 – 2010-01-26 10:30:52

+1

@ Idan:我很惊讶,我找不到它,但经过5分钟的搜索后,我放弃了;-) – 2010-01-26 10:40:17

回答

76

因此,您不要将比较(==)与赋值(=)混合在一起。

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

基本上,它是防御性编程技术之一。保护你自己。

+2

辉煌 - 非常感谢:-) – 2010-01-26 10:29:25

7

当常数是第一个时,如果意外地写入=而不是==,编译器会发出警告,因为将值赋给常量是非法的。错误

if (pMsg = NULL) return rv; 

29

要写作阻止你。然而,一个好的编译器会提醒你这个问题,所以大多数人不会使用“恒定优先”的方式,因为他们发现很难阅读。

+0

在您的忍者编辑后+1。 – 2010-01-26 10:21:33

+8

+1提到现代编译器无论如何都会提醒大家。另一个不使用C++的原因是为了避免编写错误的操作符重载的问题。 ('_bstr_t',哦,我多么恨你。) – jamesdlin 2010-01-26 10:28:39

+0

+1提到可读性/维护问题。 – Ben 2010-01-27 20:07:18

8

它停止single =赋值错误。

例如,

if (NULL = pMsg) return rv; 

将无法​​编译,其中作为

if (pMsg = NULL) return rv; 

将编译并给你头疼

2

他们说, “防止赋值和比较的混合”。

在现实中,我认为这是无稽之谈:如果你是如此纪律,你不要忘了,在左边放常数,你肯定不会混淆“=”“==” , 你会? ;)

+0

不,但是,你有更多的机会避免出现错误多次击键可能会导致键入不够难以获得第二个=。因此,你知道,错字。 – 2010-01-26 10:33:39

+0

我只是好奇你有多少次这样的错字?打赌你没有。 – 2010-01-26 10:36:33

+6

我想我认为自己很有纪律,但无论你的编码风格如何,每个人都会偶尔出现错字,这种简单的习惯可以避免像执行这样的错误。在编译时捕获的错误在执行时值10 :-) – 2010-01-26 10:38:17

2

编译器输出警告很好,但我们现实世界中的一些人不能将警告视为错误。颠倒变量和常量的顺序意味着这个简单的滑动总是显示为错误并且阻止编译。你很快习惯了这种模式,它所保护的缺陷是微妙的,一旦引入就很难找到。

8

为了澄清什么,我在一些评论中写道,这里是有原因的 ++做这在C代码。

有人写,说,串类,并决定转换运算符添加到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. 不要写你自己的字符串类。
  2. 避免隐式转换操作符,特别是在执行(1)时。

但有时你正在处理你无法控制的第三方API。例如,Windows COM编程中常见的_bstr_t字符串类遭受此缺陷。

+0

我见过很多禁止运算符重载的地方。 Yay C++。 – 2010-01-26 20:54:42

+0

不会s ==“富”有相同的问题,虽然? – 2010-01-31 19:21:42

+0

@Jon Cage:不是。不直觉地,虽然''foo“== s'不会触发期望的歧义错误,但是's == ==”foo“'。 (作者可能会实现'bool MyString :: operator ==(const char *)const',它将解决's == =='foo''歧义,但仍然无法修复'foo'== s'。) – jamesdlin 2010-01-31 20:51:55

0

我忘记了文章,但报价又是这样的:“很显然它更容易记住把恒定的第一,比它是要记住使用==”;))

相关问题