5

What's the differences of if(x==0) vs. if(!x)? Or are they always equivalent? And for different C++ build-in types of x:

  • bool
  • int
  • char
  • pointer
  • iostream
  • ...
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174

5 Answers5

3

Assuming there is a conversion from a type to something that supports if (x) or if (!x), then as long as there isn't a DIFFERENT conversion for operator int() than opterator bool(), the result will be the same.

if (x == 0) will use the "best" conversion, which includes a bool or void * converter. As long as there is any converter that can convert the type to some "standard type".

if(!x) will do exactly the same, it will use any converter that converts to a standard type.

Both of these of course assume the converter function isn't a C++11 "don't default convert".

Of course, if you have a class like this:

class
{
   int x;
  public:
   bool operator bool() { return x != 0; }
   int operator int() { return x == 0; } 
}; 

then if (x == 0) will do if ( (x == 0) == 0) and if (!x) will will do if (! (x != 0), which isn't the same. But now we're really TRYING to make trouble, and this is VERY BADLY designed code.

Of course, the above example can be made to go wrong with any operator int() that doesn't result in false for x == 0 and true for all other values.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
2

if(!x)

is "if x is not false", that means that in order to evaluate that, you might have to cast x to a bool.

>> This can be harmful and if you wish to avoid it you should use something like the Safe Bool Idiom


if(x!=0)

means "if x is not 0", so that is evaluated comparing x to 0. That might also involve an implicit conversion.

>> Be careful when using pointers this way, C++11 introduces a nullptr to avoid the confusion of NULL==0 (semantically different): What exactly is nullptr?

Community
  • 1
  • 1
Marco A.
  • 43,032
  • 26
  • 132
  • 246
1

Take into account what are you going to process

If it is a boolean, the results are pretty clear:

if (!false)   // If false TRUE
if (false==0) // If false TRUE

If it is an integer, pay attention to the ! condition

if (0==0) // Unexpected behaviors are missing..

if (!-1) // False
if (! 0) // True
if (! 1) // False

For chars both conditions give me the same results:

if (! ' ')  // nothing
if (' '==0) // nothing

if (! 'z')  // nothing
if ('z'==0) // nothing
Lucio
  • 4,753
  • 3
  • 48
  • 77
0

No this all depends on the type of x. For example,

if(cin)

is used in the stl to check if an iostream type hasn't had an error. There is no equivalent cin != 0.

Besides most operators are overloadable and conversions too.

user3125280
  • 2,779
  • 1
  • 14
  • 23
  • 3
    `if (cin != 0)` at least compiles for me; I think it has the same result as `if (cin)`. The operands are converted to a common type; I'm not sure of the details in this case. – Keith Thompson Jan 10 '14 at 07:24
  • Yes there can be multiple conversions, etc. That was a broad unchecked example - good catch though. I was just saying it has no operator int – user3125280 Jan 10 '14 at 07:25
  • Please discuss the differences on other C++ built-in types, see updated question. Thanks. – herohuyongtao Jan 10 '14 at 07:31
  • 1
    What @KeithThompson said. Once you provide an implicit conversion to `bool`, you open yourself to conversions from `bool` to other built-in types. C++11 explicit conversion operators were added to prevent this kind of thing. – juanchopanza Jan 10 '14 at 07:32
  • broadly speaking, this is too broad, sorry. if(!x) converts x to a bool, if the class provides an operator bool - otherwise it does all manner of unspeakable witchcraft (google safe bool idiom). In the other case, it is converted to an int. – user3125280 Jan 10 '14 at 07:33
  • Just for the record, I had a look, and there was a `void*` conversion operator before C++11, and now there is an explicit bool operator. – juanchopanza Jan 10 '14 at 07:53
0

Simply !x will return true for every "false" value (i.e, 0, null, false, etc.) whereas x!=0 will return true, iff x is not equal to 0.

Zeeshan
  • 2,884
  • 3
  • 28
  • 47