C语言中的“反向”条件语句

4
我正在查看一些代码,发现了一些奇怪的条件语句,具体如下:

if (NULL != buf) {...}

我想知道为什么要这样写条件语句,而不是这样写:
if(buf != NULL){...}

我一时也想不出为什么要用第一种方式,但我认为这并不是错误。在我看来,它们实现了相同的功能,但第二种方式更加直观。是否有特殊原因要使用第一种条件语句?


5
好的,我会尽力为您翻译。以下是您提供的链接中的内容:Yoda conditions是一种编程风格,在条件语句中将常量值写在变量之前。例如,代替写成if (x == 0),使用if (0 == x)。这种风格得名于星球大战系列电影中的Jedi大师Yoda,因为他经常使用倒装语序。Yoda条件的目的是避免由于手误而导致的变量赋值问题。如果我们错误地写成 if (x = 0) 而不是 if (x == 0),因为赋值操作会返回0,所以该条件将始终为false。但如果我们使用Yoda条件,写成if (0 = x),则编译器将无法将0分配给变量x,而是会产生一个编译错误,从而防止这类错误的发生。虽然Yoda条件可以避免一些常见的错误,但也可能会使代码更难阅读和理解。它们通常被认为是一种过时的编码实践,现在很少使用。 - rlbond
1
此外,'if(0==somecallThatReturns0OnSuccess(loads, of ,lengthy, parameters)){DoStuff};' 在调试时看起来更加简洁,易于跟踪。 - Martin James
4个回答

7

是的,这被称为 " Yoda conditions"。其思想是在进行检查时不会意外地赋值。大多数现代编译器应该能够捕捉到它。


4

为了避免新手犯错,如 if (buf = NULL)

if (NULL = buf) 会导致编译错误,而 if (buf = NULL) 是正确的,但语义不符合预期。


2
启用编译器警告后,if (buf = NULL)会触发“建议使用显式括号将赋值的结果作为真值”的警告信息或类似信息。 - Iharob Al Asimi

3
这个概念基本上是这样的:
新手常常会错过双等号符号“==”,而使用单个等号符号“=”。因此,教练们会教他们这种方法,以便他们不会被简单的程序卡住。
如果没有启用编译器警告,如果你这样做:
if(buf = NULL)

你基本上是将 buf 赋值为 NULL,这在语法上并没有错误,并且你不会收到任何警告,但当你这样做时:
if(NULL = buf)

编译器会抛出错误,因为它知道你不能将任何东西赋值给NULL。
为什么特别提到尤达?
这是因为尤达是《星球大战》中的角色,其对话以相反的顺序进行排列,例如“天空是蓝色的”。
您可以在这里阅读更多有趣的编码术语。

2
这将在比较表达式被误写为赋值表达式时产生编译错误。
例如,如果您编译:
if (buf = NULL) {}

编译器报错:

警告:建议在赋值用作真值时使用括号[-Wparentheses]

但是如果您将其更改为

if (NULL = buf) {}

编译器现在报错:
error: 需要左值作为赋值的左操作数。

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