32

I noticed for a while now the following syntax in some of our code:

if( NULL == var){
   //...
}

or

if( 0 == var){
  //...
}

and similar things.

Can someone please explain why did the person who wrote this choose this notation instead of the common var == 0 way)?

Is it a matter of style, or does it somehow affect performance?

jscs
  • 63,694
  • 13
  • 151
  • 195
RomanM
  • 6,363
  • 9
  • 33
  • 41
  • 1
    Lots of answers about the 'why' of the practice - for completeness, the practice has no effect on performance. – Michael Burr Dec 16 '08 at 03:28
  • 19
    It depends on who's performance you are talking about, reading code backwards slows my performance :) – Robert Gamble Dec 16 '08 at 04:05
  • 1
    @Robert: Agreed - but I find myself still using it sometimes. I'm embarrassed to say that every now again I get bit by the damn 'assignment hidden in a conditional' bug. – Michael Burr Dec 16 '08 at 04:10
  • 1
    @MikeB: I make the mistake on occasion too which is why I keep the warnings turned up on the compiler, I've never been "bitten" by it because the compiler has always caught it. – Robert Gamble Dec 16 '08 at 05:03
  • 1
    Caveat: If `var` is of complex type (e.g. smart pointer) and implements `bool operator==(T *p) const` as well as `operator T*()`, this may have [side effects](https://stackoverflow.com/questions/49168637/shared-pointer-constness-in-comparison-operator/49169757#49169757). – Martin Hennings Mar 08 '18 at 10:41
  • FYI, it is called [Yoda Conditions](https://en.wikipedia.org/wiki/Yoda_conditions). – Alexis Wilke Oct 24 '22 at 17:56

7 Answers7

44

It's a mechanism to avoid mistakes like this:

if ( var = NULL ) {
  // ...
}

If you write it with the variable name on the right hand side the compiler will be able catch certain mistakes:

if ( NULL = var ) {  // not legal, won't compile
  // ...
}

Of course this won't work if variable names appear on both sides of the equal sign and some people find this style unappealing.

Edit:

As Evan mentioned in the comments, any decent compiler will warn you about this if you enable warnings, for example, gcc -Wall will give you the following:

warning: suggest parentheses around assignment used as truth value

You should always enable warnings on your compiler, it is the cheapest way to find errors.

Lastly, as Mike B points out, this is a matter of style and doesn't affect the performance of the program.

Robert Gamble
  • 106,424
  • 25
  • 145
  • 137
  • 3
    Most compilers worth their salt will give you a warning for the first example. – Evan Dec 16 '08 at 04:21
  • Yep, as I just commented in the question my compiler has always caught this for me, I'll update the answer. – Robert Gamble Dec 16 '08 at 05:04
  • 2
    Not only should you enable warnings on the compiler - you should pay attention to them, and revise the code so that the warnings cease to appear. Otherwise, you end up with builds with thousands of warnings...which are a complete pain. (I work on one such - it infuriates me!) – Jonathan Leffler Dec 16 '08 at 05:50
  • 2
    And when I say 'revise the code', I don't just mean 'insert random casts until the warnings cease', which is a common misinterpretation of how to fix a lot of compiler warnings. – Jonathan Leffler Dec 16 '08 at 05:51
14

If you mistakenly put

if ( var = NULL )

instead of

if ( var == NULL )

then there will only be a compiler warning. If you reverse the order:

if ( NULL == var )

then there will be a compiler error if you put

if ( NULL = var )

Personally, I hate to read code written that way, and I only made that mistake once in my first year of coding. =)

Kieveli
  • 10,944
  • 6
  • 56
  • 81
  • 3
    This is why my students are required to compile with -Wall -Werror. So I don't have to read the ugly stuff :-) – Norman Ramsey Dec 16 '08 at 03:48
  • I saw this style in all over [PHP Symfony source-code](https://github.com/symfony/symfony/blob/24680199a8c3b7b3ffc2f0e50f96b77b62975b90/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php#L203). It's not only unappealing, it's just confusing. PHP has no compiler (at least not in the way C++ has) and I get the point out of it, but my humble opinion is that experienced developers that still need this just *worth* that bug. It's a hard to debug like uninitialized variables. They commit it first time, then no more. Anyway, readability first IMHO. – Niki Romagnoli Sep 27 '21 at 11:10
8

Corollary: try to use const as much as you can.

const int val = 42;

if (val = 43) {
    ...
}

will not compile.

Ates Goral
  • 137,716
  • 26
  • 137
  • 190
  • 5
    I'm all for using const wherever possible but you don't usually check the value of constant variables nearly as often as you do variables that actually change so I don't know how much this would really help. The easiest way to avoid these kinds of errors is to enable compiler warnings. – Robert Gamble Dec 16 '08 at 05:27
  • 1
    another idea is to do if(+val = 43) and even if val is non-const, it still won't compile :) – Johannes Schaub - litb Dec 16 '08 at 05:42
  • @litb: That's an interesting idea but it will only work for arithmetic types (not pointers). – Robert Gamble Dec 16 '08 at 05:56
  • 2
    Robert, these are the darn diffs between C and C++ :/ in C++ +ptr is possible and yields an rvalue. – Johannes Schaub - litb Dec 16 '08 at 07:30
  • I didn't know about that difference between C and C++ - cheers :-) – James Hopkin Dec 16 '08 at 09:55
  • @RobertGamble I guess it is true for constants (who compares constants?!). However, I very often define a variable within my functions once and I don't expect to ever change it, then I mark it `const`. That way I avoid many potential mistakes. i.e. I'd rather have 10 such `const` variables than reusing the same variable 10 times. – Alexis Wilke Oct 24 '22 at 17:45
7

To avoid the

if (var = NULL)

bug

jpoh
  • 4,536
  • 4
  • 35
  • 60
5

Quoting Joel On Software, The Guerrilla Guide to Interviewing:

Occasionally, you will see a C programmer write something like if (0==strlen(x)), putting the constant on the left hand side of the == . This is a really good sign. It means that they were stung once too many times by confusing = and == and have forced themselves to learn a new habit to avoid that trap.

(I'm not really a fan of this "best practice".)

Federico A. Ramponi
  • 46,145
  • 29
  • 109
  • 133
  • 3
    hehe, (0 == strlen(x)) is actually a bad sign, ('\0' == x[0]) would be good :) – quinmars Dec 16 '08 at 09:39
  • *hehe, (0 == strlen(x)) is actually a bad sign, ('\0' == x[0]) would be good* -1, smug. `0 == strcmp(...)` is the same pattern, and there's no shortcut. – Andrew Henle Sep 19 '17 at 10:50
  • 1
    @AndrewHenle `'\0' == x[0]` is actually great if you can guarantee `x` is never `NULL`, which, in many cases, you can. It always runs in constant time while `strlen(x)` doesn't. – cebola Oct 13 '18 at 18:24
  • @AndrewHenle Note that `if (strlen(x) = 0)` would never have compiled, even when C was first created. So I guess that's an altogether bad example. – Alexis Wilke Oct 24 '22 at 17:48
  • @cebola Note that `strlen()` does not verify the input parameter and if `NULL`, your program `SEGV`. So the `x[0]` will not be any different in this example. – Alexis Wilke Oct 24 '22 at 17:49
1

Just by the way, I've observed over many years teaching C to new programmers that if you train yourself to read "=" as "gets" and "==" as equals, that in itself will save you from a lot of these bugs. Then you read

if( x = 0){

as "if x gets 0 then" and that begins to sound weird.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
  • 1
    That is a good idea only if you're never going to read any mathematics in your life again :p – ShreevatsaR Dec 16 '08 at 03:55
  • If I'm being careful in explaining code to somebody else, I tend to use "is assigned" for =. – Greg Hewgill Dec 16 '08 at 04:06
  • Shree, you do this all the time if you're moving from math to computers, and even in math. Consider saying when we say T(n)=O(n) -- that "=" isn't an "equals", it's an abuse of the notation to say it is. Calling the "=" symbol "gets" just acknowledges this. – Charlie Martin Dec 16 '08 at 11:07
1

Personally, I prefer

if (!x) {