Sign in to follow this  
TFS_Waldo

"if (! expression)" Or "if (expression == false)"??

Recommended Posts

Hey, everyone. This does not really concern anything about my current project. But I was thinking about it, so I decided to start some kind of conversation. LoL. I hope it's not bother. =) Anyhow, which statement do you recommend/prefer? if (! expression) { // Code here } Or if (expression == false) { // Code here } I mean, I used to use "(! expression)", but I started checking to see if the "expression" was actually "false/true/etc.". I don't really know why. But is there really a standard for this? Or is it more of a preference depending on the person who is coding? Because, the way I look at it, it makes it easier for me to understand exactly what I'm evaluating the expression against. And it actually makes it a little bit easier to see "== false" than "! expression". Sometimes I'll look at code, and either I'll forget the "!", or I'll read over it, and not realize that it's there. So what does everyone else think? Which method do you use? =) I didn't intend to "waste" anyone's time. But it just popped into my mind. And I wanted to get some answers. =) Thanks in advance, Matt U.

Share this post


Link to post
Share on other sites
Just like he said above... if you are using ==, put false before expression, so the compiler tells you that "false" isn't a lvalue. I prefer to use !expression than (expression == false). Also, I prefer to use (expression) over (expression != 0) or (expression == true) on values or boolean stuff or anything.

Share this post


Link to post
Share on other sites
Quote:
Original post by TFS_Waldo
Hey, everyone. This does not really concern anything about my current project. But I was thinking about it, so I decided to start some kind of conversation. LoL. I hope it's not bother. =)

Anyhow, which statement do you recommend/prefer?

It depends on what expression is. In general, you should try to phrase a conditional positively -- that is, "if (expression)..." rather than "if (!expression)" -- because positives are less complicated and easier to read than negatives. For instance:
if (shouldStripWhitespace)                  if (!shouldStripWhitespace)
{ {
// section A right // section B
} <====== }
else ======> else
{ wrong {
// section B // section A
} }
Ultimately, consistency is more important, so whichever you decide to do, stick to it.

Share this post


Link to post
Share on other sites
Never explicitly use true or false in your conditionals. It's dumb and superfluous.

If you have something like this:
if (a > b == true)
what it means is this:
Evaulate a > b, which gives true.
Then compare true == true
See? Unless you seriously expect true to not equal true, don't bother with the last part.

Same goes for false. If you wanted to test if the above was false, you could do this:
if (a > b == false)
which would get evaluated like this:
evaluate a > b, which gives false
evaluate false == false, which gives true
Or maybe a < b is true?
Then we get true == false, which is false.
Again, why would you bother to test whether false equals false?
Why not just test whether the original expression failed to hold?
!(a > b) would have done the trick.

Otherwise, when do you stop?
a > b yields true
Let's compare that with true, like so:
a > b == true
that yields true *too*. So should we also compare that with true?
a > b == true == true ?
And hey, guess what, that gives us another bool, so we need to compare that with true
a > b == true == true == true

And so on. If you think that makes it "easier to read", or more intuitive, it's because you either don't understand what's going on inside the if statement, or because you haven't thought about it.
If you take it apart like I did above, it's not very intuitive at all.
The first expression returns a simple bool as well, so the simplest, easiest and clearest solution is to just use that, rather than compare it to an infinite number of bools to get the final bool, which you're for some reason more willing to use than the previous ones.

As for what LessBread said, it's true, in *some* cases it'll catch that error. But better not rely too heavily on it, because it won't always work, like in the following:

bool b = false;
if (b = expression)
The meaning is the same as in his example, but the compiler won't catch the missing =. So if you expect it to do that for you, you're in for a load of nasty bugs.

Anyway, that's what a professor at uni once spent a full hour telling us. I guess it made an impression on me...
Still, personal preferences, I guess. If you prefer statement == true == true == false, then hey, go ahead.

[Edited by - Spoonbender on April 22, 2006 8:31:49 AM]

Share this post


Link to post
Share on other sites
The only way that could possibly make any sense is if a is a class with an overloaded == and ! operators (though whoever overloaded them to work like that should be shot). Fortunately the people I work with would never do that, nor would that write that if a was a boolean, though I hear it does happen at some places.

tj963

Share this post


Link to post
Share on other sites
I think boolean is better because look:

if (!someVal)
the void is my mind reads this as if not someVal and I can visual and see in one eye, very terse.

if ( someVal == false )
this just says too much. the voice in my mind reads this as if someVal is false. The time consumed in interpretting expressions takes longer.

Share this post


Link to post
Share on other sites
Surely it depends on the variable or expression? If you're checking a variable called, say, "we_want_to_do_this_particular_thing", then "if (we_want_to_do_this_particular_thing) {}" is more readable than putting '==true' after it, whereas if your variable or expression is terse, e.g. "read", then '== true' helps comprehension.

But you know, each to their own, as long as they're consistent.

Share this post


Link to post
Share on other sites
It's generally bad form to compare directly for true because in many languages (C/C++ in particular) any value that is non-zero is considered to be true. e.g.:

int x = 2;
if (x) whatever(); // whatever gets run
if (x == true) whatever(); // whatever *does not* get run

In C++ if you only ever use real "bool" booleans you can compare directly against true and be safe but it's still bad form and risky IMHO.

You can compare directly against false. I personally don't, but you can.

Share this post


Link to post
Share on other sites
Quote:
Original post by Spoonbender
if (a > b == false)
which would get evaluated like this:
evaluate a > b, which gives false
evaluate false == false, which gives true
Or maybe a < b is true?
Then we get true == false, which is false.
Again, why would you bother to test whether false equals false?
Why not just test whether the original expression failed to hold?
!(a < b) would have done the trick.

(a > b) is the same as !(a <= b), not !(a < b).

Share this post


Link to post
Share on other sites
I did some performance tests some time ago (many years in fact). Using if(a==0) is faster than doing if(!a). I never dug into the assembly code so I can't give you more details. So in portions of the code which is really important I use comparison. But sometimes I want compact code than I use the negation. So its you decision which one you use.
Anyway maybe compilers have improved so this may not longer be true.

Luck!
Guimo

Share this post


Link to post
Share on other sites
Quote:
Original post by Guimo
I did some performance tests some time ago (many years in fact). Using if(a==0) is faster than doing if(!a). I never dug into the assembly code so I can't give you more details. So in portions of the code which is really important I use comparison. But sometimes I want compact code than I use the negation. So its you decision which one you use.
Anyway maybe compilers have improved so this may not longer be true.

Any compiler will emit exactly the same code for those. (Well, assuming integers.) Your benchmark was flawed.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anon Mike
It's generally bad form to compare directly for true because in many languages (C/C++ in particular) any value that is non-zero is considered to be true. e.g.:

int x = 2;
if (x) whatever(); // whatever gets run
if (x == true) whatever(); // whatever *does not* get run

In C++ if you only ever use real "bool" booleans you can compare directly against true and be safe but it's still bad form and risky IMHO.

You can compare directly against false. I personally don't, but you can.
I couldn't agree more with this post.

Also, comparing against true is especially dangerous in VB because of the way -1 is true in VB, not +1. Just the other day I solved a bug on the line:
if myCheckbox.Value = true
Hint: vbChecked exists for a reason.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by bakery2k1
Quote:

Quote:

Original post by Spoonbender
(lots of bullshit)

This is the stupidest post I've read in a long while. And I even prefer (!expr) myself.

Actually, he's completely correct.
Maybe as much as I'm completely correct in saying that peanuts are better than apples, because peanuts are smaller. The essential difference between !expr and expr==false (assuming expr is bool) is 6 characters. Some may find that the extra 6 characters highlight the negation better than a single character would, and can you truly argue with that? Well, he tried and I found it to be completely moronic.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Quote:
Original post by Guimo
I did some performance tests some time ago (many years in fact). Using if(a==0) is faster than doing if(!a). I never dug into the assembly code so I can't give you more details. So in portions of the code which is really important I use comparison. But sometimes I want compact code than I use the negation. So its you decision which one you use.
Anyway maybe compilers have improved so this may not longer be true.

Any compiler will emit exactly the same code for those. (Well, assuming integers.) Your benchmark was flawed.


I really can't confirm or deny your comment as I never checked the generated Assembly code. But I recall the test was really simple... but please don't ask me to remember the details as it was a long time ago.

But I recall doing this using Visual Studio 6 and with my old computer... a PIII 550Mhz, 256Mb RAM. Also I was optimizing for my Blitting Engine (using DX5/6 in that time) so I tried to squeeze every cycle from it but never checked the output code. (Finally I dropped all the C++ code for pure assembly and I gained 2X or more speed.)

But anyway if you ask me, the generated assembly code shouldnt be exactly the same. Probably:
if(a==true)
---------------
mov ax, [a]
cmp ax, 1
je [somewhere]

if(!a)
---------------
mov ax, [a]
not ax
cmp ax, 0
je [somewhere]

Now my assembly may be a little rusty so I guess some optimizations may be done. Maybe using jz instead of comparing and jump (cmp, je). But I really doubt those two instructions may give the same code.

Luck!
Guimo


Share this post


Link to post
Share on other sites
I am almost sure that an if without comparisons would be faster, however on today's compiler's i doubt that it would matter.

if (value) should generate to something like
mov ECX, value
jz END_IF

while if(!value) should generate to something like
mov ECX, value
not ECX
jz END_IF

if you were doing something like if (value == false) then you would get an extra comparison instead of a not. The not would be faster.

Share this post


Link to post
Share on other sites
Quote:
Original post by Guimo
...

Now my assembly may be a little rusty so I guess some optimizations may be done. Maybe using jz instead of comparing and jump (cmp, je). But I really doubt those two instructions may give the same code.

I just verified it for you. Exactly the same code is emitted. My guess is, your benchmark was being screwed up by a page fault early on, and that the order you tested them in became a factor. As you said, though, that was a while ago, so there's no way to know for sure what you did wrong.
Quote:

But anyway if you ask me, the generated assembly code shouldnt be exactly the same. Probably:
if(a==true)
---------------
mov ax, [a]
cmp ax, 1
je [somewhere]

if(!a)
---------------
mov ax, [a]
not ax
cmp ax, 0
je [somewhere]


Of course not, in that situation. The two code snippets there do different things. But that's not the situation we're considering.

Share this post


Link to post
Share on other sites
I don't know about other compilers but I read/listened to some slides/audio from one of the VS2005 developers and he definitly stated that the more common case should be first in an if statment (since that is the way the compiler optimizes it).

Share this post


Link to post
Share on other sites
Quote:
Original post by OrenGL
I don't know about other compilers but I read/listened to some slides/audio from one of the VS2005 developers and he definitly stated that the more common case should be first in an if statment (since that is the way the compiler optimizes it).


We're talking about the syntax for the if-condition, not the sense of it.

But anyway, you normally would put the more common case first because that's what a maintenance programmer will expect to see - unless the if-statement is implementing an early-out (guard clause, e.g. "if (ICantHandleThis()) { return; }").

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this