When returning a boolean, why use "!!" - c++

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
}

Related

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

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.

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.

Difference between !(variable) and (!variable)

In either C or C++, is there a conclusive difference between using !(variable) and (!variable) in an if-statement, such as:
if (!(variable)) { .. // do something }
or
if (!variable && !(variable2)) { .. // do something }
such that one version delivers a different result over the other?
Its all about order of operation. Using !(variable) will evaluation all conditions inside of the parenthesis then do the ! (or NOT) to determine whether to enter the if statement where-as (!variable will do the NOT specifically on the variable itself.
So in the situations:
!(true && false) = true
!(true && true) = false
(!true && !false) = false
(!true && true) = false
!(true && !false) = false
...and so on
Hope this helped.
The only way it would make a difference is if the variable is an expression, then its a matter of operator precedence. Otherwise && has lower precedence than !
There is no difference between
!(variable)
and
(!variable)
but if you are using operators that has different precedence you will have a difference. For example, if you write
!(varible1 && variable2)
is not the same as
!varible1 && variable2
because the NOT will be applid to the whole operation in the first case and only to varible1 in the second case.
May be you are getting a problem with the evaluation, C has lazy evaluation, so when the execution detects that boolean evaluation has a result, it doesn't try the other values. So, now consider instead of variables you have functions.
int foo() { printf("foo\n"); return 1; }
int bar() { printf("bar\n"); return 0; }
If you write
if (foo() && bar()) { ... }
you will get
foo
bar
but if you write
if (bar() && foo()) { ... }
you will only get
bar
because the evaluation will be false, doesn't matter the result of foo
No, in your example the first one (although the parens are unbalanced :)) behaves exactly like it would if there were no parentheses, and the second behaves the same way. You can even do this
if ((!((((variable)))))) { ... }
But don't :)
They should never evaluate to different things. Parentheses used this way are really for grouping operations, but in this case, you're not grouping any operations, just the expression itself.
So !(x) is just a pedantic way of writing !x
Now, if you had an operation inside the parentheses, that's where the differences start.

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