Why put the constant before the variable in a comparison?
Solution 1
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.
Solution 2
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. =)
Solution 3
Corollary: try to use const
as much as you can.
const int val = 42;
if (val = 43) {
...
}
will not compile.
Solution 4
To avoid the
if (var = NULL)
bug
Solution 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".)
Comments
-
RomanM almost 2 years
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?
-
Michael Burr over 15 yearsLots of answers about the 'why' of the practice - for completeness, the practice has no effect on performance.
-
user2522201 over 15 yearsIt depends on who's performance you are talking about, reading code backwards slows my performance :)
-
Michael Burr over 15 years@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.
-
user2522201 over 15 years@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.
-
Martin Hennings about 6 yearsCaveat: If
var
is of complex type (e.g. smart pointer) and implementsbool operator==(T *p) const
as well asoperator T*()
, this may have side effects.
-
-
Norman Ramsey over 15 yearsThis is why my students are required to compile with -Wall -Werror. So I don't have to read the ugly stuff :-)
-
sidgeon smythe over 15 yearsThat is a good idea only if you're never going to read any mathematics in your life again :p
-
Greg Hewgill over 15 yearsIf I'm being careful in explaining code to somebody else, I tend to use "is assigned" for =.
-
Evan over 15 yearsMost compilers worth their salt will give you a warning for the first example.
-
user2522201 over 15 yearsYep, as I just commented in the question my compiler has always caught this for me, I'll update the answer.
-
user2522201 over 15 yearsI'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.
-
Johannes Schaub - litb over 15 yearsanother idea is to do if(+val = 43) and even if val is non-const, it still won't compile :)
-
Jonathan Leffler over 15 yearsNot 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 over 15 yearsAnd 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.
-
user2522201 over 15 years@litb: That's an interesting idea but it will only work for arithmetic types (not pointers).
-
Johannes Schaub - litb over 15 yearsRobert, these are the darn diffs between C and C++ :/ in C++ +ptr is possible and yields an rvalue.
-
quinmars over 15 yearshehe, (0 == strlen(x)) is actually a bad sign, ('\0' == x[0]) would be good :)
-
James Hopkin over 15 yearsI didn't know about that difference between C and C++ - cheers :-)
-
Mr.Ree over 15 yearsIt's also just a little too easy to miss the ! when looking over someone elses code...
-
Charlie Martin over 15 yearsShree, 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.
-
Andrew Henle over 6 yearshehe, (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. -
cebola over 5 years@AndrewHenle
'\0' == x[0]
is actually great if you can guaranteex
is neverNULL
, which, in many cases, you can. It always runs in constant time whilestrlen(x)
doesn't. -
TechNyquist over 2 yearsI saw this style in all over PHP Symfony source-code. 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.