Programing question

Lets say there is a function that returns a value named func1. I sometimes see code like the following:

if (“ok” == func1() ) {

// do something

}

Why are such expressions used, as opposed to:

if (func1() == “ok”) {

// do something

}

I recall reading about this some time ago, but try as I might, I can’t find any information about this now. If anyone can direct me to some resources or can explain the possible advantages of using the first form, I’d appreciate it.

Is the question about “ok” == func1() vs. func1() == “ok”? I cannot conceive of any situation in which the two have different semantics (there’s an order of evaluation thing in play, but “ok” being just a constant expression with no side-effects, that shouldn’t matter here, and besides, that’s all standard-less anyway…). Of course, you have to write it one way or another.

Are you sure you didn’t mean to ask about something else? This seems pretty trivial.

There is absolutely no reason to prefer one over the other assuming the language allows that at all.

What you will see, sometimes, is people writing things like this:


if (3 == a) { foo(); }

instead of this:


if (a == 3) { foo(); }

The reason is that the compiler (usually) will not warn you if you miss an equals sign and type:


if (a = 3) { foo(); }

which assigns 3 to a and always executes foo(). That is usually not what you want to do there (and if it is, you should be shot).

Yes.

Right. My question is: “why is the first form used?” I’m assuming there is a good reason.

And we’re both telling you there isn’t. Some things just come down to arbitrary personal style, and that is one of them.

(Having some consistent, readable style is essential. Arbitrary points of style, however, really don’t matter.)

Actually Derleth, you did give a possible good reason, thanks. And I realize this is trivial, but it’s been bugging me.

I think Derleth’s observation about triggering compiler warnings if you screw up and use “=” instead of “==” is very good, the best you’ll get. Other than that, no, there doesn’t need to be a good reason, any more than there’s a good reason that some people will write “a * 7” and others will write “7 * a”.

ETA: Ah, but you see that now. This post has been mooted.

In Java it is to prevent the NPE as explained here in point 4.

Assuming that the evaluation of a string literal has no side effects, and as long as the comparison is legitimate (i.e., the result of func1() can be checked for equality with a string under the typing rules of the language in question, and that syntax is a valid way to compare those types), then it’s purely a question of style.

One reason to use this convention for equality checks containing literals is that it can help avoid a common type of error, the inadvertent use of a single-equals assignment (’=’) when the double-equals comparison (’==’) is intended. In most languages, trying to assign a value to a literal will result in a compiler error, so if you’re in the habit of putting the non l-value operand first, you will be notified by the compiler whenever you accidentally omit an ‘=’. If you place an l-value first, it will quietly perform the assignment, and the result (that you happen to be using in a control statement) will not be what you expect.

In some languages this isn’t really a concern; for example, C# will not allow you to implicitly convert any type to a boolean, and the compiler will issue a warning if you have such a constant boolean expression in a control statement, so this mistake in C# will always result in a compiler error or a warning, regardless of which style you choose. However, it’s worth noting that neither GCC nor Microsoft’s C/C++ compiler will give such a warning by default.

Now, there’s another reason you would need to be careful about the order of operands in a comparison, but it only applies when both operands can have side effects (for example, if both operands are function evaluations). In some languages, most notably C and C++, you have to make sure that the side effects cannot affect each other in any way, since the language makes no guarantees about which operand will be evaluated first. That is,

if(foo() == bar()) { … }

and

if(bar() == foo()) { … }

are the same thing as far as the language specifications are concerned, so if foo() has a side effect that might change the way bar() operates, the result of the comparison is undefined. The same goes for expressions using the post-increment or pre-increment operators. Some languages (like Java) are more forceful about evaluating things left-to-right, so this wouldn’t be a concern.

EDIT: And, of course, I see that my main points have already been brought up by Derleth and Indistinguishable. Serves me right for taking the time to write up a long reply. :smiley:

don’t ask brings up a good point about the Java NPEs too.

This is it exactly. It was a trick recommended by Steve Maguire in his excellent (although possibly dated) book Writing Solid Code It doesn’t trigger a warning though, in C/C++ it triggers an error and simply won’t compile, so you’ll never have an unintended assignment when you meant a comparison.

Sorry, of course; “error” rather than “warning”.

Still could have an unintended assignment rather than comparison, though, in cases when both sides are potential l-values. [Though I suppose that just means the trick can’t always be employed]

Exactly. In C, unlike in FORTRAN, you cannot change the value of 3. :slight_smile:

(Yes, some very old FORTRAN compilers (that only knew about MONOCASE LETTERS) would allow programmers to assign a new value to what should have been a numerical constant. Chalk it up to a very simple parsing algorithm.)

Precisely right. Nothing really beats testing, but picky compilers can certainly help in many cases.

Thanks everyone for responding.

In reviewing the code that triggered my question, I think I realize why someone would choose this particular style. It went something like:

if (“ok” == someLongObtuseFunctionNameGoesHere(Param1, Param2) )

This is more readable than the alternative:

if (someLongObtuseFunctionNameGoesHere(Param1, Param2) == “ok” )

This is because the function return value it is testing against makes immediate sense to a human reader, and putting it right next to the “if” is helpful. It wouldn’t necessarily be more readable in a case like:

if (1034923 == someLongObtuseFunctionNameGoesHere(Param1, Param2) )

Also, if someLongObtuseFunctionNameGoesHere() returns a null, the second form will trigger a null pointer exception in some languages, and the the first won’t.

When I used to be a grad assistant, our FORTRAN environment had a version of this which resulted from the literal table protections combined with FORTRAN’s call-by-reference semantics. If you called function foo() with a literal argument of, say, 3, it actually passed a reference to a location containing 3. The compiler created a literal table that typically only had one instance of each constant, so that all literal 3’s were references to that one location. Normally, if you tried to then change the value of the argument passed as a literal, you got a runtime error because the literal table was protected read only. For some reason, students encountering that error were perpetually discovering the obscure compiler argument which changed the permissions on the literal table rather than figuring out that they shouldn’t try to change an argument passed as a literal. With the comical result that they would then change the value of “3” globally through their whole program.

Just out of curiosity, are there actually languages where if(a == b) is legitimate code which can trigger a null pointer exception? [As opposed to, say, if(a.equals(b))] I can’t think of one off the top of my head, but the top of my head is fairly narrow, so to speak…

Hmm… Good question. I’ll have to think about that.

It should be possible in any language that allows operator overloading (and generates null pointer exceptions, of course). For example, in C#, you could define the following class:


public class Foo
{
   private String text;

   public Foo(String s)
   {
      text = s;
   }

   public static Boolean operator == (Foo a, String b)
   {
      return a.text == b;
   }

   public static Boolean operator != (Foo a, String b)
   {
      return !(a == b);
   }
}

If you then try to compare a null “Foo” reference to a string [e.g. Foo f = null; if ( f == “hello”) { … } ] the comparison will generate a NullReferenceException.