Compare Constants From The Left

 if (LAUNCH_NUCLEAR_WEAPONS == currentSituation){
is much safer than

 if (currentSituation == LAUNCH_NUCLEAR_WEAPONS){
because when you forget that second = mark, you'll have an invalid assignment, and can catch it at CompileTime.

Of course, another solution is to use a language that isn't so vulnerable to this problem. (Two examples: in PythonLanguage "=" and "==" are never both valid; in the LispFamily of languages, assignment and equality testing don't look at all similar.) :-)

That sounds icky. I prefer to reserve my option to do really stupid stuff like b=a+(c==d); or if(b==a+(c=d)){} You can do the first of those in both Python and Lisp. You can do the second in Lisp but not in Python.

First, you should of course use a compiler that warns for this and statements without effects like:

currentSituations == LAUNCH_NUCLEAR_WEAPONS;

For what happens when you want to compare two values? The strategy to put the constant to the left doesn't work and you can't get the protection you've learnt to rely on. And what happens when you forget to put the constant to the left? If you think this wouldn't happen, you assume that you're aware of the pitfall and you'd be able to avoid it anyway. What if you by mistake assume that LAUNCH_NUCLEAR_MISSILES is a constant when it's actually mutable?

when you forget that second = mark...

What if I forget the first?

No. Use Lint. Or a compiler such as gcc/GnuCpp (GarethMcCaughan) or MicrosoftCorporation's VisualCeePlusPlus (DaveHarris) that can catch such errors, and turn on all the compiler's warning flags.

that's "and use Lint"...

I prefer to do
  if (x == 5) { stuff... }
on the grounds that it's easier to read. Lint will warn me if I mess up, and I code and test very carefully anyway. (And if you're not coding very carefully in C++ already, then I'm inclined to think you should use some other language anyway! ;-) -- JeffGrigg

It is my job to write good software, not lint's. -- AnonymousDonor

It's lint's job to catch silly obvious errors. (Code reviews would do the same, but I've yet to find an organization with sufficient maturity to do them consistently.) -- JeffGrigg

I use gcc/GnuCpp with all its warning flags turned on. I can't remember the last time I made an error that (1) could be caught by a convention like this one and (2) wasn't immediately caught by the compiler. -- GarethMcCaughan

You know, I have forced myself to apply this rule for years because I haven't internalized it. I almost always write the constant on the right, catch myself, and move it to the left. In every case, I have never suffered from the == vs = confusion. I attribute my success not because I am some C++ god (although feel free to come to that conclusion), but because I am so anally cognizant about this rule. I find that the real C++ gods have become comfortable (or at least anal) with rules like this. Reminds me of the riddle, "Who leaks memory in C++? Java programmers." -- SunirShah

Concur. I always put the constant on the right because it just reads "better" to me that way. In over twenty years I have checked in code containing the assignment versus the evaluation twice. The first time was my first major project in C and the second time, years later, was some quickie fix that I didn't test adequately. Fixed both before the product got out of the lab. -- MartySchrader

This is quite useful in Java when comparing Strings. If you compare Stings using
	if ("stringconstant".equals(stringvariable)) { .... }
instead of
	if (stringvariable.equals("stringconstant")) { .... }
you automatically avoid the potential NullPointerException when stringvariable is null.

I would say you ignore it, rather than avoid it. It could bite you somewhere else. But only if you let the potentially null variable propagate. Don't do that; use the NullObject pattern. The idiom of "".equals() is quite useful.

I feel these arguments are based on way too much "guru knowledge" of the compilers in use. Probably well less than half of the comparisons I write are against constants, so I do not think this rule really has enough applicability to overcome my natural tendencies to put the constant on the right. -- WayneMack
my natural tendencies to put the constant on the right

From an abstract mathematical point of view, it doesn't make any difference which order you put the arguments when you test for equality. So why does it feel so natural to put the constant on the right?

In algebra, you'd write x=5 instead of 5=x. In English, you'd generally say "Jack's hair is red" instead of "Red is the color of Jack's hair", putting the known (constant) value last.

I frequently end up with 5=x, depending on how I solved the equation. The English example isn't really equivalent, because "red" is an adjective while "Jack's hair" is a noun. You can't put an adjective in the subject of a sentence, so you have to add "the color" before switching it around (equivalent to a typecast in C/Java ;)). I tend to use "Red is the color of Jack's hair" and "The color of Jack's hair is red" about equally, with a slight preference for the first. -- JonathanTang

My focus is on the variable, my culture reads left to right, I feel like the things I focus most on should go leftmost. Having said that, I put the constant on the left, since there's no guarantee the guy who gets my code will have access to a compiler (or lint) which yells at him, or the initiative to tinker with compiler warning levels. And, it's not excusable to say 'well, that's his problem', since a) it could cause me to get called in for a long (boring) debug session and b) it reflects poorly on me.

OTOH, English tends towards leading adjectives, while Romance Languages tend towards trailing adjectives ("red shirt" vs "la chemise rouge"). Any Francophone programmers care to weigh in on the "naturalness" of 5 == x vs x == 5? --PeteHardie

[I also agree, language-wise, five equal variable seems less proper than variable equal five]

I think it's more natural to put the variable first, because you get more context earlier that way, so you have to do less mental backtracking.

For example, if I read "if (foo_counter == 5)", I know early on that we are testing how many foos we have counted.

If I read "if (5 == foo_counter)", when I get to the "5 ==" part, I still don't know what the units of the "5" are, so the "5" is mostly meaningless and doesn't stick in my brain very well. After I see "foo_counter", I then backtrack to the "5", which now sticks in my brain better because it has a context to help it stick.

I suspect it's mostly due to something called the Sapir-Whorf hypothesis of linguistic relativity. According to this, our language affects the way we think, as has been speculated previously. English, as a language, employs what is called "topic-comment syntax, which means that we state what we are talking about (a variable), and then make a comment about it (assignment). Examples include 'the car is red' (car.colour = red;) and "the boy ran across the road" (boy.action = running; = oppositeRoadSide;). Of course, this leads to the original question of why comparisons, specifically, require the rValue on the right. Note that "topic-comment syntax" is only the deep structure of language - the surface structure (what is actually said) may feature extraposition (rearrangement of syntactic elements).

gcc adapts the convention that an assignment used in an if/while clause produces a warning (assuming the flag is enabled) unless an extra level of parentheses is used. In other words,
 if (x = function()) { ... }
produces a warning, but
 if ((x = function())) { ... }
does not.

This is very friendly of gcc, but I find the resulting code to be mildly unaesthetic.

A recent attempt to insert a trojan into the LinuxOs kernel (one which was detected almost immediately, and not released) consisted of code sort of like this:
 if ( /* obscure condition to activate trojan */ && (pProcess->uid = 0))
	retval = EINVAL;
Note the assignment rather than a comparison in the if statement. The result of that code fragment would be to give the process running such code root privileges.

It would have just saved me 20 mins debugging. Then again, not being naughty and writing a unit test for my 'simple fix' probably would have too. Why do we do bad things when we know they're bad?

How about using TestFirstDesign? This will catch the problem of the assignment rather than comparison. The first test would verify the code without the if clause. The if clause would only be inserted to respond to a second test. Of the two tests, one would continue to fail until the underlying if statement was corrected.

Of course, in several BASIC dialects, you never had such problems, since you had to do let x = 5;, iirc. But seriously, using := for assignment and == for comparison and NOT using a single = at all, would solve this. But in languages that don't do this, I try to HaveThisPattern too. -- AalbertTorsius

Just make all variables final or const unless required otherwise. That catches a whole host of such errors. -- WouterLievens? (see ConstCorrectness)

There is also the English languages that use = for assignment and IS or IS NOT for comparison

See Also: CeeIdioms, JavaIdiom, AssignmentVsEqualityOperator
CategoryDefensiveProgramming, CategoryIdiom, CategoryConditionalsAndDispatching, CategoryCee, CategoryCpp

View edit of January 9, 2014 or FindPage with title or text search