Condition checking: if(x==0) vs. if(!x) - c++

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
...

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.

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?

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

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.

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.

Related

When returning a boolean, why use "!!"

I saw some C++ code like this:
bool MyProject::boo(...)
{
bool fBar = FALSE;
....
return !!fBar;
}
I couldn't think of any difference between returning fBar directly in this case and returning !!fBar. How two negatives make a difference?
Thank you
In your example, there's no difference between returning fBar and returning !!fBar.
In other cases, e.g. when a user-defined type such as BOOL (typedef-ed to be int) is used, the !! construct has the effect of coercing any non-zero value to true; i.e. !!fBar is equivalent to fBar ? true : false. This can make a difference if fBar can be 5 and you want to compare it against TRUE, which is defined to be (BOOL)1.
This is typically done to avoid compiler warnings in situations when a non-bool value has to be converted to bool type. Some compilers (like MSVC++) issue a "performance" warning when a non-bool value is implicitly converted to bool. One way to suppress this warning is to use an explicit conversion. Another way is to use the !! combination.
However, in your case the argument of return is already declared as a bool, meaning that the above reasoning does not apply. (Are you sure it was bool and not, say, BOOL?). In that case there's no meaningful explanation for that !!.
!! "is" "to boolean" operator (not really, it is two negate operators). It make no different is this case. However, it will make difference if is not bool.
e.g.
int fBar = 2; // !!fBat evaluate to 1
bool b = (fBar == true) // this is false
b = fBar; // this is true
b = !!fBar; // this is also true
typedef int MyBool; // say some library use int as boolean type
#define MY_TRUE 1
#define MY_FALSE 0
MyBool b2 = fBar; // this evaluate to true, but not equal to true
if (b2 == MY_TRUE )
{
// this code will not run, unexpected
}
if (b2)
{
// this code will run
}
MyBool b3 = !!fBar;
if (b2 == MY_TRUE )
{
// this code will run
}
if (b2)
{
// this code will run
}

How to have both functions called with logical AND operator (&&) c++

Let's say I had two functions and a variable,
int number;
bool foo (void);
bool footoo (void);
And in each of these functions, some logic with the variable number takes place, such as:
number++;
return(rand()%2);
And then I call them like so:
if (foo() && footoo())
{
cout << "Two foo true!"
}
Why aren't both functions being called and how can I guarantee both functions are called and increment number, regardless of return value?
In C (and included in C++ by default) the && operator is short-circuiting. This means that as soon as the condition is deemed false the other operand is not evalulated. It allows us to do things like if(ptr && ptr->value == 10) without having to do the pointer validity check before the value check in a separate if statement.
If you want to run both functions, run both functions and save off the results:
bool b = foo();
if(foobar() && b)
{
// Stuff
}
Simplest thing I can think of: Assign the return values of both to variables and check those:
bool fooIsTrue = foo();
bool footooIsTrue = footoo();
if(fooIsTrue && footooIsTrue)
// ...
They aren't being called right now because && short-circuits, that is, when the left is false the whole expression is sure to be false so the right side is skipped.
This is useful for constructions where for example you want to first check if you can access something before you check it like so:
if(somePtr != NULL && somePtr[0] == 1)
Why aren't both functions being called? It's called "short-circuit evaluation" and is an efficiency feature of C++. The rationale (roughly) is that code called in the context of a test is generally side-effect-free, and therefore if you can establish that the test is going to fail by only evaluating the leftmost expression, you should do so.
Your code is not side-effect-free, so short-circuit evaluation is not a feature that helps you in this case.
In order to guarantee both functions are called, you'll need to call them separately from the test of their return values:
bool fooRet = foo();
bool footooRet = footoo();
if (fooRet && footooRet)
{
cout << "Two foo true!"
}
In an if statement where && is involved (something like if (a && b && c && d)), if the 1st condition is false, then the rest of the condition in the if isn't evaluated anymore and the false "block" is executed.
The same thing happens with ||. If you have if (a || b || c || d) and a is true, then the rest of the condition isn't evaluated and the true "block" is executed.
If you want both of them to be called, just assign them to two boolean variables like bool myB1 = foo(), myB2 = footoo(); and then do if (myB1 && myB2).
&& and || are what we call short circuit operators. What this means is that if by evaluating the first argument we can tell the truthiness of the whole expression we stop and don't evaluate the next expression.
For example if in this statement a && b is a is false we know the whole statement cannot be true and thus it is ok to stop. With || we can stop if the first statement is true.
If you want both functions to be called the first one must return a value that can be evaluated as true. You can do this if you want both to be called.
bool a = foo();
bool b = footoo();
if (a && b)
{
cout << "Two foo true!"
}
This way both are called.
In C++ bool's are guaranteed to be a 1 or 0 so the bitwise operators are actually the same as the short circuit it terms of the result. However I would not use them for readability.
Becasue with statement if(first && second) , if first is not true, second is not even checked.

boolean variables for loops vs conditions

Here is my code:
int main()
{
int input;
bool isZero = false;
while (!isZero)
{
...
if (0 == input)
{
isZero = true;
}
else
{
isZero = false;
}
}
return 0;
}
the program does what its supposed to, but I feel like the !isZero expression is not foolproof.
is
bool isZero = false;
while(!isZero);
{
....
}
the same thing as
bool isZero = false;
while(isZero == false)
{
...
}
why or why not?
Also, in which cases does true represent 1, and in which cases does it represent any nonzero number?
While requires the condition to be a Boolean and !isZero is already a Boolean. Equality operator generates a Boolean, so again isZero == false is a Boolean. So the only thing you changed is adding another operator and (possibly) slowing down loop a little (AFAIR comparison is slower than bit operators).
Operations on Boolean values are similar to operations on integer values. Your concerns can be then translated into integers: "Hey, x == 1 is not foolproof, I have to check, whether x - 1 == 0".
The bottomline is, that !isZero is absolutely foolproof enough.
As for int to bool conversions, the standard says,
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. For direct-initialization (8.5), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.
C++ is very lenient in its requirements for a conditional. It accepts booleans, and it will implicitly cast any integer to a boolean (where 0 is false and non-zero is true), and it will also implicitly cast any pointer to a boolean (since pointers are unsigned integers. In that case, NULL would be false, and any other pointer would be true). Thus, the following all evaluate to true, so the while will execute.
int i = 4;
char c = '0';
bool b = true;
void * p = 0xdeadbeef;
while (i) // ...
while (c) // ...
while (b) // ...
while (p) // ...
While the following won't evaluate to true, so the while won't execute.
int i = 0;
char c = '\0';
bool b = false;
void * p = NULL;
while (i) // ...
while (c) // ...
while (b) // ...
while (p) // ...
According to C++, all of these are allowed.
When you're looking at a boolean in your expression, it's redundant to put a == operator on it. Whether b above is true or false, it makes perfect sense to say while (b), and you don't need while (b == true). As for all of the others, each programmer makes their own choice. My personal preference is to explicitly compare all non-booleans. The statement int i = 5; while (i) may be legal in C++, but it just doesn't read clearly. I would much rather see int i = 5; while (i != 0). It's unnecessary, but doesn't cost you any extra processor operations, and is explicit as to its intent.

if (!someArray[i])

I have a simple question for C.
What does this statement mean?
if (!someArray[i])
I know that the operator ! means NOT. But i cannot get my head around it.
Thank you!!
if (!someArray[i]) means if someArray[i] is zero (or convertible to false) then the code inside the if block will be executed, otherwise it will not be executed!
If someArray[i] is not convertible to boolean value OR if the type of someArray[i] doesn't define the operator ! returning boolean value (or a value convertible to it), then your code will not compile.
Note: all numbers (int, float, double, char, etc) and pointers of any type, are convertible to boolean value.
In C, it's equivalent to writing
if (someArray[i] == 0)
From the C language standard (n1256):
6.5.3.3 Unary arithmetic operators
Constraints
1 The operand of the unary + or - operator shall have arithmetic type; of the ~ operator, integer type; of the ! operator, scalar type.
Semantics
...
5 The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E).
As Kos and John Dibling pointed out, the situation in C++ is different. From the latest C++ draft (n1905)
5.3.1 Unary operators
...
8 The operand of the logical negation operator ! is implicitly converted to bool (clause 4); its value is true if the converted operand is false and false otherwise. The type of the result is bool.
It means simply that if the value in someArray[i] is interpreted as false (either a zero value, or boolean false), then the code will enter the if block.
Assume the following uncompiled/untested code:
//we make an array with some chars, but have one as NULL (0)
char someArray[] = { 'a', 'b', 'c', 0, 'e' };
//we loop through the array using i as the index
for(int i = 0; i < 5; ++i)
{
if(!someArray[i]) //if this entry is null (0) or false, show an error:
{
printf("%d does not have a char!\n", i);
}
else //otherwise, print the contents
{
printf("%d is %c\n", i, someArray[i]);
}
}
Expected output would be:
0 is a
1 is b
2 is c
3 does not have a char!
4 is e
The ! (not) operator will return true if the expression evaluates to a 0. So:
class SomeObject
{
}; // eo class SomeObject
std::vector<int> intVector;
std::vector<long> longVector;
std::vector<SomeObject*> objectVector;
intVector.push_back(1);
intVector.push_back(0);
longVector.push_back(4049);
longVector.push_back(0);
objectVector.push_back(new SomeObject);
objectVector.push_back(NULL); // or nullptr if you're on C++0x, or even just 0!
if(!intVector[0])
{
// false, intVector[0] is not zero.
}
if(!intVector[1])
{
// true! intVector[1] is zero
};
And the same holds true for the other two vectors. Incidentally, the ! operator can be overidden by a class to change the behaviour.
Note also, that this is different from C# which requires that the expression be of a boolean type:
int i = 0;
if(!i) { /* compile error in C# */ }
if(i == 0) { /* ok in C# */ }
bool b = false;
if(!b) { /* ok in C# */ }
if(!(i == 0)) { /* also ok */ }
Perhaps the important thing to know about in the statement if (!someArray[i]) is the precedence of the operators.
first [ is evaluated, then ! is evaluated.
Writing it in a longer form might be
sometype a = someArray[i];
if(!a)

retval = false && someFunction(); // Does someFunction() get called?

I'm currently working with the Diab 4.4 C++ compiler. It's a total POS, non ANSI-compliant, and I've found problems with it in the past.
I'm wondering if the following problem is an issue with the compiler, or a shortcoming in my knowledge of C++
I realize that the form of x = x && y; will short-circuit the y part if x is false. What the compiler is doing is short-circuiting in the case of x = x && y(); where y() is a non-const function.
class A
{
int _a;
A(int a) { _a = a; }
bool someFunction() { _a = 0; return true; }
};
main(...)
{
A obj = A(1);
bool retval = false;
retval = retval && A.someFunction();
/* What is the value of A._a here? */
}
What seems wrong to me is the fact that the compiler is doing this short-circuiting even though someFunction() is not a const function. If it's not const, is the compiler overstepping its bounds by skipping A.someFunction() when retval is false?
Also, I realize this issue can be avoided by writing retval = A.someFunction() && retval; but I'd really like to know why this is happening.
Short circuiting applies to all expressions, regardless of const-ness. Skipping the call to someFunction() is correct.
The && and || operators are defined to evaluate lazily, this is the way the language works. If you want the side effects to always happen, invoke the function first and stash the result, or refactor the function to split the work from the state query.
As others have explained, || and && always perform short-circuit evaluation.
Also note that short-circuit evaluation can be very useful, since it lets you write code like this:
retval = obj_pointer && obj_pointer->SomeBooleanMethod();
Without short-circuit evaluation, this would crash on a NULL pointer.
It doesn't matter if the second operand to && is const or not. After the first operand evaluates to false the return value is known, so there's no reason to evaluate the second operand.
If the function has side effects that require it to be executed, put it first.
Short-circuit evaluation has nothing to do with const or non-const. It happens no matter what.
The statement A() && B(); will do exactly what if (A()) B(); does (although it isn't a perfect substitute, as the second one allows an else). This is sometimes used to change a statement into an expression (such as when writing a macro, or embedding it in another statement).
The && operator is also called the shortcut operator, which means it only evaluates the second part if the first part returned true. That's the main difference between && and &:
value = func1() && func2(); // evaluates func2() only if func1() returns true
value = func1() & func2(); // evaluates both func1() and func2()
For && operator,
1 && X = X
0 && X = 0
so in case first var is 0, compiler will evaluate the expression to 0, no question, what ever the X is.
Compiler will ignore the X part as it wont impact the result. Here X can be any thing function/variable/expression.....