views:

1854

answers:

14

This is a purely pedantic question, to sate my own curiosity.

I tend to go with the latter option in the question (so: if (boolCheck) { ... }), while a coworker always writes the former (if (boolCheck == true) { ... }). I always kind of teased him about it, and he always explained it as an old habit from when he was first starting programming.

But it just occurred to me today that actually writing out the whole == true part may in fact require an additional step for processing, since any expression with a == operator gets evaluated to a Boolean value. Is this true?

In other words, as I understand it, the option without the == true line could be loosely described as follows:

  1. Check X

While the option with the == true line would be more like:

  1. Let Y be true if X is true, otherwise false
  2. Check Y

Am I correct? Or perhaps any normal compiler/interpreter will do away with this difference? Or am I overlooking something, and there's really no difference at all?

Obviously, there will be no difference in terms of actual observed performance. Like I said, I'm just curious.

EDIT: Thanks to everyone who actually posted compiled results to illustrate whether the steps were different between the two approaches. (It seems, most of the time, they were, albeit only slightly.)

I just want to reiterate that I was not asking about what is the "right" approach. I understand that many people favor one over the other. I also understand that, logically, the two are identical. I was just curious if the actual operations being performed by the CPU are exactly the same for both methods; as it turns out, much of the time (obviously it depends on language, compiler, etc.), they are not.

+15  A: 

I would expect the difference to be optimised away by any half-decent compiler.

(I just checked with C# and the compiled code is exactly the same for both syntaxes.)

LukeH
They are the same in C#, but not in other languages.
UncleO
@uncleo:This is not a matter of a language, but of a specific compiler.
stormsoul
@stormsoul: This is a matter of language. The OP doesn't mention C#, and the two expressions are not equivalent in C or C++. Of course, the machine instructions will be different in these languages for any compiler.
UncleO
@stormsoul: To be more clear, one expression asks if boolCheck is equal to 1, the other expression asks if boolCheck is not equal to 0.
UncleO
@uncleo: The two expressions *are* equivalent in C++ if you use the native bool type. I'd be extremely surprised if the compiler didn't deduce that and optimise away any differences. (Although it's possible that the optimisation is skipped because the performance characteristics of both sets of machine-code are *exactly* the same.)
LukeH
@uncleo: My answer wasn't stating that the C# way is the one true way, I just happened to have a C# project open at the time so I did a quick test.
LukeH
@Luke: I know, and I wasn't criticizing you. I just noticed that the OP didn't mention C#. The bool type in C# and boolean in Java were developed in a response to bugs appearing in C, where bool is just another typedef for int. Even now, the OP says that the two expressions are logically identical. This is an unfortunate misunderstanding to be propagating.
UncleO
A: 

It depends on the compiler. There might be optimizations for either case.

Daniel A. White
A: 

There is no logical difference, presuming there is no internal typecasting going on, e.g., testing fstream.

ifstream fin;
...
if( ! fin)
...
Paul Nathan
+8  A: 

The compiler should generate the same code. However, comparing with true is arguably better because it is more explicit. Generally I don't do the explicit comparison, but you shouldn't make fun of him for doing it.

Edit: The easiest way to tell is to try. The MS compiler (cl.exe) generates the same number of steps in assembly:

int _tmain(int argc, _TCHAR* argv[])
{
    bool test_me = true;

    if (test_me) {
004113C2  movzx       eax,byte ptr [test_me] 
004113C6  test        eax,eax 
004113C8  je          wmain+41h (4113E1h) 
        printf("test_me was true!");
    }

    if (test_me == true) {
004113E1  movzx       eax,byte ptr [test_me] 
004113E5  cmp         eax,1 
004113E8  jne         wmain+61h (411401h) 
        printf("still true!");
    }
    return 0;
}

At this point the question is do test and cmp have the same cost? My guess is yes, though experts may be able to point out differences.

The practical upshot is you shouldn't worry about this. Chances are you have way bigger performance fish to fry.

jeffamaphone
But the steps aren't the same. One uses test and je, the other uses cmp and jne. I think je and jne will be the same performance, but I don't know the difference between test and cmp.
SchlaWiener
And I compiled debug without optimizations. It may be different in release with full optimizations.
jeffamaphone
You should make two functions that you call from main where the if takes place to avoid any weird optimizations.
jmucchiello
@SchlaWiener, yeah, it becomes dependent on the hardware implementation of those instructions at this point. I don't know either.
jeffamaphone
@jmucchiello, I think it's pretty clear here that it isn't doing any wierd optimizations. No registers are getting re-used, etc. Plus it was compiled in debug with no optimizations.
jeffamaphone
Oh, and compile them in separate files with full optimization: void boolfunc(bool b) { if (b) printf("true"); } and in a separate file void boolfuncistrue(bool b) { if (b == true) printf("true"); } Then call them both from main, compile the three files and see what you get.
jmucchiello
You need separate compilations so the compiler doesn't inline the functions directly into main.
jmucchiello
I'd argue (and have) that the explicit comparision has no benefit and can lead to subtle bugs (depending on the language, of course): http://stackoverflow.com/questions/356217/should-i-use-isgood-or-isgood-false/356709#356709
Michael Burr
I would agree with @Michael Burr -- avoid the explicit comparison. At best, in some languages, it's an invitation to a bug, e.g., mistyping "if (check == true)" as "if (check = true)" if the compiler allows the construct.
tvanfosson
@jmucchiello, I'm not that interested in this experiment. @Michael Burr, @tvanfosson, yes, that is an argument against it. Again, I'm not encouraging this convention, merely stating that there there are arguments to be made for doing it. In the example given of accidental assignment inside of a conditional, most modern compilers have a warning for that if you compile at a high enough level. Which I encourage everyone to do.
jeffamaphone
Thanks for this answer, which addresses the point I was curious about in my actual question: whether or not the compiled steps are the same. It seems, at least with the MS compiler, they are not.
Dan Tao
"My guess is yes, though experts may be able to point out differences." -- One difference I think is that the cmp opcode is bigger (because it includes the constant `1` as one of its arguments).
ChrisW
This is only an MSVC implementation detail, other compilers may do it differently. Still, some people were talking about the efficiency of this specific assembly code. Yes, both CMP and TEST take 1 clock cycle on nearly all CPUs - so the code is equivalent. All versions of the conditional jump instruction are also equivalent in performance. The one teeny weeny detail I'd like to point out is that the CMP instruction is 1 byte longer, which makes the second code slightly bigger :). Still, it's a negligible difference.
stormsoul
It is not "more explicit" if you start with a good name for the value ;) --- In C++, the meaning is subtly different: if (b) tests for b being non-zero (i.e. not false), if (b==true) tests for b being 1 (or whatever exact value the platform uses for true). That's why the difference in the assembly
peterchen
Disagree - it is not "more explicit". It's redundant - you don't need to specify "== true" in a boolean expression. To do so is a "code smell" that indicates the programmer doesn't really know how a boolean expression works.
Colen
@Colen: That's not true and you are just generalizing. Yes, it *can* indicate that the coder does not really understand the boolean type, but I work with a very experienced and very intelligent developer you uses the explicit comparison. It is his style, and he definitely understands booleans. He wrote the most well written, extensible, and robust application in our company's portfolio, he just prefers that convention.
Ed Swangren
To be perfectly honest, I am far more wary of programmers who throw around the term "code smell".
Ed Swangren
+11  A: 

I think the comparison with true shows a lack of understanding by your partner. Bools should be named things to avoid this (such as isAvaliable: if (isAvailable) {...}).

rlbond
+1  A: 

The MSVC++ 6.0 compiler generates slightly different code for the two forms:

4:        if ( ok ) {
00401033   mov         eax,dword ptr [ebp-8]
00401036   and         eax,0FFh
0040103B   test        eax,eax
0040103D   je          main+36h (00401046)
....
7:        if ( ok == true ) {
00401046   mov         ecx,dword ptr [ebp-8]
00401049   and         ecx,0FFh
0040104F   cmp         ecx,1
00401052   jne         main+4Bh (0040105b)

The former version should be very slightly faster, if I remember my 8086 timings correctly :-)

anon
Timing truths from the 8086 days probably aren't accurate for today's processors.
Joe White
Is that optimized code? Is 'ok' a boolean type? I wonder why it wouldn't just test or compare 'byte ptr [ebp-8]' instead of lading into a register; or, test or compare cl and/or al instead of using bitwise and followed by a 32-bit test or compare.
ChrisW
It is not optimised. It is C++ code and ok is a bool.
anon
@Joe Hence the smiley.
anon
I'm pretty sure that "test r,r" and "cmp r,i" will have the same timings on a modern processor. Same with "je" and "jne". Probably would've been a difference back in the 8086 days though.
LukeH
@Luke It's irrelevent IMO because the code isn't optimized. Given a true bool type, I'd *hope* [!] that the compiler might emit identical code.
ChrisW
+3  A: 

Here's the Python (2.6) disassembly:

>>> def check(x): return (bool(x) == True)

>>> import dis
>>> dis.dis(check)
  1           0 LOAD_GLOBAL              0 (bool)
              3 LOAD_FAST                0 (x)
              6 CALL_FUNCTION            1
              9 LOAD_GLOBAL              1 (True)
             12 COMPARE_OP               2 (==)
             15 RETURN_VALUE        
>>> def check2(x): return bool(x)

>>> dis.dis(check2)
  1           0 LOAD_GLOBAL              0 (bool)
              3 LOAD_FAST                0 (x)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE

I suppose the reason check isn't optimized is due to Python being a dynamic language. This in itself doesn't mean Python uses a poor compiler, but it could stand to do a little type inference here. Maybe it makes a difference when a .pyd file is created?

Mark Rushakoff
+1  A: 

This gets into specific languages and what they consider "truthy" values. Here's two common ones: JavaScript and PHP.

The triple equals operator in both these languages assures that you really are checking for a boolean type of truth. For example, in PHP checking for if ($value) can be different from if ($value==true) or if ($value===true):

$f = true;
$z = 1;
$n = null;
$a = array(1,2);

print ($f)        ?'true':'false'; // true
print ($f==true)  ?'true':'false'; // true
print ($f===true) ?'true':'false'; // true
print "\n";
print ($z)        ?'true':'false'; // true
print ($z==true)  ?'true':'false'; // true
print ($z===true) ?'true':'false'; // false
print "\n";
print ($n)        ?'true':'false'; // false
print ($n==true)  ?'true':'false'; // false
print ($n===true) ?'true':'false'; // false
print "\n";
print ($a)        ?'true':'false'; // true
print ($a==true)  ?'true':'false'; // true
print ($a===true) ?'true':'false'; // false
print "\n";
print "\n";

I expect that languages one speaks daily will inform how one views this question.

artlung
Actually in PHP the === operator makes sure the two values share the same type. That has nothing to do with the truthiness of the value. FALSE!==0 but if (0) is operationally identical to if (FALSE). I'm pretty sure JS works the same way.
jmucchiello
@jmucchiello I added an addition to be clearer about what I mean by differences between leaving out an equality operator, double equals, and triple equals. Sorry I was unclear.
artlung
+1  A: 

Testing for equality to true can lead to a bug, at least in C: in C, 'if' can be used on integer types (not just on boolean types), and accept any non-zero value; however the symbol 'TRUE' is one specific non-zero value (e.g. 1). This can become important with bit-flags:

if (flags & DCDBIT)
{
    //do something when the DCDBIT bit is set in the flags variable
}

So given a function like this ...

int isDcdSet()
{
    return (flags & DCDBIT);
}

... the expression "if (isDcdSet())" is not the same as "if (isDcdSet() == TRUE)".

Anyway; I'd think that an optimizing compiler should optimize away any difference (because there is no logical difference), assuming it's a language with a true boolean (not just integer) type.

ChrisW
A: 

It may not be the same if you are working with a nullable bool.

Example:

Bool? myBool = true

if(myBool)  // This will not compile

if(myBool == true)  //this will compile
Sergio
that is because it is not a bool anymore it is an Nullable<Bool> object, which obviously not the type that is used in the if statement
Nick Berardi
+5  A: 

Duplicate question (http://stackoverflow.com/questions/356217/should-i-use-isgood-or-isgood-false). Here's a pointer to my previous answer:

The technique of testing specifically against true or false is bad practice if the variable in question is really supposed to be used as a boolean value (even if its type is not boolean) - especially in C/C++. Testing against true can (and probably will) lead to subtle bugs.

See the following SO answer for details:

http://stackoverflow.com/questions/356217/should-i-use-isgood-or-isgood-false/356709#356709

Michael Burr
Michael: I saw the above question before posting this one. In my opinion this is not a duplicate of that; the person asking that question was inquiring about what is best in practice; I am asking specifically if the explicit check involves an additional processing step, without any consideration for what is better or worse.
Dan Tao
In that case, the answer to your question for C/C++ is that unless the variable in the expression is of type bool, they *cannot* generate the same code because the code is semantically different (even if ever so slightly). However, it's likely that the generated code will be exactly equivalent in terms of performance.
Michael Burr
+2  A: 

There may be some justification in the "boolCheck == true" syntax dependning on the name of the variable you're testing.

For example, if the variable name was "state", then you can either have:

if (state) {
   ...
}

or you can have

if (state == true) {
   ...
}

In this case, I think the latter form is clearer and more obvious.

Another example would be a variable like "enabled", in which case the first form is clearer.

Now having a boolean variable called "state" is bad practice, but you may have no control over that, in which case the "== true" syntax may improve code readability.

skaffman
If I were writing C#, I would know that state must be boolean and thus true/false. If I were writing C, I have no idea if == true is even correct in this instance. Perhaps it means any state defined except that which has value 0 in which case the latter construct is wrong (and certainly not an improvement). Better to refactor the code to make it clearer than to introduce redundant constructs, IMO.
tvanfosson
I agree. I'm just trying to come up with some justification for why someone might do it.
skaffman
+1 for caring about what the code is saying to the programmers.
ChrisW
I dunno, I used to always do `== true` but I find that it just ends up cluttering the code more. If you name your variables well, you don't need the `== true` part. For example `if (rocketFired) { ... }`.
cdmckay
Umm, yes, that's what my answer said.
skaffman
+2  A: 

In my experience if (flag==true) is bad practice.

The first argument is academic:

If you have a bool flag, it is either true or false.

Now, the expression

(flag==true)

again, is true or false - it is no more expressive, only redundant - flag can't get "more true" or "more false" than it already is. It would be "clearer" only reason only if it's not obvious flag is a boolean - but there's a standard way to fix that which works for all types: choose a better name.

Stretching this beyond reaso, the following would be "even better":

((flag==true)==true)

The second argument is pragmatic and platform-specific

C and early C++ implementations had no real "bool" type, so there are different conventions for flags, the most common being anything nonzero is true. It is not uncommon for API's to return an integer-based BOOL type, but not enforce the return value to be 0 or 1.

Some environments use the following definitions:

#define FALSE 0
#define TRUE (!FALSE)

good luck with if ((1==1) == TRUE)

Further, some platforms use different values - e.g. the VARIANT_BOOL for VB interop is a short, and VARIANT_TRUE is -1.

When mixing libraries using these definitions, an explicit comparison to true can easily be an error disguised as good intentions. So, don't. When mixing such code,

peterchen
A: 

IMHO it's a bad idea to use the if (boolCheck == true) form, for a simple reason : if you accidentally type a single 'equals' sign instead of a double (i.e. if (boolCheck = true)), it will assign true to boolCheck and will always return true, which would obviously be a bug. Of course, most modern compilers will show a warning when they see that (at least the C# compiler does), but many developers just ignore warnings...

If you want to be explicit, you should prefer this form: if (true == boolCheck). This will avoid accidental assignation of the variable, and will cause a compile error if you forget an 'equals' sign.

Thomas Levesque