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.
Related
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.
Ran across some code that used this, which led me to wonder.
if(condition) foo = bar();
condition && (foo = bar());
Are these two segments of code equal to a compiler? If not, in what ways would they differ?
Due to operator precendence, the latter is interpreted as:
(condition && foo) = bar();
Additionally, there is a possibility of && being overloaded, which may result in pretty much anything.
So in short: they are not equal at all - at least in general case.
The first version is just a plain old statement.
The second version is an expression that will return the result of the entire expression. That probably allows some tricky one-line syntax that, as per usual, could potentially make code more readable but will more likely make it more complex and harder to parse quickly due to unfamiliarity.
IMO either use it everywhere consistently so that readers of your code get used to it, or don't use it at all.
Unless && is overloaded for the combination of types of condition and foo they will have identical behavior - the latter will work this way:
bool result;
if( !condition ) {
result = false;
} else {
foo = bar();
result = foo != 0;
}
and result gets ignored
that's usual short-circuiting - if the first component of && is false the second is not evaluated.
IMO the second variant is much less readable.
Unless condition && foo evaluates to an lvalue , condition && foo = bar(); is meaningless.
There is a compiler error: invalid l-value. To have same functionality you must use
conticion ? foo = bar( ) : <other accion>;
If && is not overloaded for neither condition nor foo:
condition && (foo = bar());
will be treated as
(condition.operator bool()) && (foo = bar());
if (condition.operator bool()) isn't true, (foo = bar()) won't be executed and vice versa.
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.
(I don't have a serious need for this answer, I am just inquisitive.)
Can every if-else construct be replaced by an equivalent conditional expression using the conditional operator ?:?
Does every if-else constructs can be replaced by an equivalent conditional expression using conditional operator?
No, you've asked this backwards. The "bodies" of if/else contain statements, and it is not possible to turn every statement into an expression, such as try, while, break statements, as well as declarations. Many "statements" are really expressions in disguise, however:
++i;
blah = 42;
some_method(a,b,c);
All of these are statements which consist of one expression (increment, assignment, function-call, respectively) and could be turned into expressions within a conditional.
So, let's reverse the question, since it sounds like you really want to know how equivalent if/else statements are to ternary conditional expressions: Can every conditional expression be replaced by equivalent if/else statements? Almost all, yes. A common example is return statements:
return cond ? t : f;
// becomes:
if (cond) return t;
else return f;
But also other expressions:
n = (cond ? t : f);
// becomes:
if (cond) n = t;
else n = f;
Which starts to point to where conditional expressions cannot be easily replaced: initializations. Since you can only initialize an object once, you must break up an initialization that uses a conditional into using an explicit temporary variable instead:
T obj (cond ? t : f);
// becomes:
SomeType temp;
if (cond) temp = t;
else temp = f;
T obj (temp);
Notice this is much more tedious/cumbersome, and requires something type-dependent if SomeType cannot be default-constructed and assigned.
On the surface of it, no. The conditional operator is an expression (that is, it has a value), while if/else is a statement (thus has no value). They fulfill different "needs" within the language syntax.
However, since you can ignore expression values, and since any expression can be turned into a statement by adding a semicolon, you can essentially emulate if/else with a conditional expression and two auxiliary functions:
// Original code:
if (condition) {
// block 1
}
else {
// block 2
}
// conditional expression replacement:
bool if_block() {
// block 1
return true;
}
bool else_block() {
// block 2
return true;
}
// Here's the conditional expression. bool value discarded:
condition ? if_block() : else_block();
However, having said that, I'm not sure it's anything more than a curiosity...
No, of course not. For reasons already mentioned, and more!
#include <cstdlib>
#include <iostream>
int main()
{
if(int i = std::rand() % 2)
{
std::cout << i << " is odd" << std::endl;
}
else
{
std::cout << i << " is even" << std::endl;
}
}
Check out where is is declared. It's not an often used technique, but it can be used in situations like COM where every call returns HRESULT which is (almost always) zero on success (S_OK), non-zero on failure, so you might write something like:
if(HRESULT hr = myInterface->myMethod())
{
_com_raise_error(hr);
}
The ternary operator can't do anything analogous.
if( cond )
break;
else
a=b;
can not always be replaced by ?: operator. You can often (if not always) rethink your whole code to provide for this substitute, but generally you can't put anything that controls execution into ?:. break, return, loops, throw, etc.
In principle, yes:
if (A) B; else C
becomes
try {
A ? throw TrueResult() : throw FalseResult();
// or: throw A ? TrueResult() : FalseResult();
} catch (TrueResult) {
B;
} catch (FalseResult) {
C;
}
Compared to using procedures (which are more natural), this allows break, continue, return etc. It requires evaluation of A doesn't end with TrueResult/FalseResult but if you use those exceptions only to simulate if, it won't be a problem.
Using the conditional operator results in an expression and both potential results of the conditional operator must be 'compatible' (convertible to the same type).
An if-else construct need not even 'return' any type much less the same one from both branches.
The conditional operator expects to have both of the items following the ? be rvalues (since the result of a conditional operator is itself an rvalue) - so while I'm not entirely an expert on the C/C++ standards, my intuition would be that the following would be disallowed (or failing that, extremely poor coding style...):
(condition) ? return x : return y;
whereas the if-else version would be quite standard:
if(condition) return x;
else return y;
Now, that said, could you take any program and write a similarly functioning program that didn't use if-else? Sure, you probably could. Doesn't mean it would be a good idea, though. ;)
GCC has statement expression, using it you can rewrite if statements to equivalent ?: expressions:
if (<expression>)
<statement1>
else
<statement2>
EDIT: The void casts serves two purpose. The subexpressions in ?: must have the same type, and without the void cast the compiler may print warning: statement with no effect.
(<expression>)? (void)({<statement1>}) : (void)({<statement2>});
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.....