这两个表达式 (bCondition == NULL) 和 (NULL==bCondition) 有什么区别?

15
在浏览 MSDN 网站时,我发现很多地方都使用了(NULL == bCondition)这样的条件检查方式。使用这种方式的目的是什么?能否提供一些示例来解释一下?
谢谢。

12
许多问题中,karthik/user692270接受了@karthik的答案。停止这种虚假的刷赞行为。 - Sebastian Mach
6个回答

29

NULL == condition 的使用在发生打字错误时提供了更有用的行为,当赋值运算符 = 被意外地使用而非比较运算符 == 时。

if (bCondition = NULL)  // typo here
{
 // code never executes
}

if (NULL = bCondition) //  error -> compiler complains
{
 // ...
}

在前一种情况下,C编译器会发出警告,而许多语言中则没有此类警告。


他是在说 = 还是 == - Oscar Mederos
我认为他在询问“==”吗? - Jess
1
@Jess:主要目的是,如果有人忘记在比较运算符中放置赋值运算符,它将抛出错误。这就是为什么在 MSDN 网站上使用这样的比较,如 NULL == bCondition。 - karthik
+1 - 好的,我没注意到你是在提到用户输错了。 - Jess
@Oscar,他的意思是NULL = bCondition会被编译器标记为错误。我建议阅读《Expert C Programming: Deep C Secrets》,它有很多技巧和窍门可以帮助避免错误。 - shebaw

13

这被称为Yoda Conditions(Yoda 表达式)。 (原链接,需要高声望才能查看)。

它旨在防止在条件语句中意图使用相等比较符号==而错误地使用赋值符号=。如果你习惯于使用 Yoda 表达式并且因笔误而写成=而不是==,那么代码将无法编译,因为你不能将 rvalue 赋值。

这是否值得这种尴尬?有人持反对意见,认为编译器在发现条件表达式中出现=时会发出警告。我认为,在我的一生中只有两三次犯这个错误,这并不足以证明我要改变我写过的所有 MLOCs 的约定。


6
@Flavius:不完全是被删除了,只是需要足够的声望才能看到它。我无法理解 SO 上的管理员删除一切的趋势。它至少可以迁移到 Programmers SE。 - Yakov Galka
1
现在有一个关于它的维基页面。 - Benjamin

9
没有区别。这是一种古老的防御性编程方式,已经过时超过20年了。其目的是为了防止在比较两个值时意外输入=而不是==。从1990年发布的Borland Turbo C开始,每个已知的编译器都会警告“可能不正确的赋值”,当您成功输入此错误时。

因此,写(NULL == bCondition)与相反的做法并没有更好或更差的实践方法,除非您的编译器非常古老。您不需要费心以任何特定顺序编写它们。

您应该关注的是,采用一种编码风格,在if/loop条件内永远不要编写赋值语句。没有理由这样做。这是C语言完全多余、有风险和丑陋的特性。所有行业事实上的编码标准都禁止在条件中进行赋值操作。

参考文献:

  • MISRA C:2004 13.1
  • CERT C EXP18-C

MSVC默认情况下不会警告您此错误。 - shebaw
2
@shebaw 令人印象深刻的是,他们竟然能够制作出比1991年的TC还要糟糕的编译器。换一个新的编译器吧。 - Lundin
2
我厌恶Yoda风格。有很多比把语言倒过来写更好的方法来避免这个缺陷。 - David Hammen

8
许多人更喜欢写NULL == bCondition,这样他们就不会意外地将NULL值赋给bCondition。
由于打字错误,有时会写成

而不是==,导致代码出现错误。
bCondition == NULL 

他们最终写下了
bCondition = NULL // the value will be assigned here.

在某些情况下,

NULL = bCondition // there will be an error

4

这只是一个良好的防御措施。有些人可能会觉得这更方便阅读。如果在分配时出现打字错误而不是使用相等运算符,编译器将尝试修改NULL,它不是一个左值并且会产生一个错误消息。当使用bCondition = NULL时,编译器可能会产生一个关于使用分配作为真值的警告信息,这个消息可能会被忽略。


也许您拼写了“lvalue”和“rvalue”的术语错误? - beduin
6
我们中的一些人认为这很不方便阅读,至少会让人们好奇为什么有人要这样做! :-) - Bo Persson
@Bo Persson:你是对的。我稍微改了一下回答。 - Michael Foukarakis

1
通常情况下,variable == valuevalue == variable之间没有区别,原则上也不应该有区别,但在C++中,如果涉及运算符重载,通常情况下会有区别。例如,虽然预计==是对称的,但某些人可能会编写一个不对称的病态实现。
微软的_bstr_t字符串类在其operator==实现中存在不对称问题。

存在使用不对称性的有效情况。例如,当实现智能指针时,将==运算符放在以原始指针为参数的类内完全合理。在这种情况下,颠倒顺序将导致编译错误。 - SomeWittyUsername

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接