Reputation: 2178
if( (A) && (B) )
{
//do something
}
else
//do something else
The question is, would the statement immediately break to else if A was FALSE. Would B even get evaluated?
I ask this in the case that B checking the validity of an array index say array[0] when the array is actually empty and has zero elements. Therefore throwing a segfault because we are trying to access something that is out of bounds of the array. Specifically
if( (array.GetElements() > 0) && (array[0]))
array[0]->doSomething();
else
//do nothing and return
This may be dangerous if array[0] actually gets evaluated because it segfaults without the first check to the left of the '&&'. Precedence tells me that the left side will definitely take precedence but it doesn't tell me that it won't evaluate the right side if the left is FALSE.
Upvotes: 20
Views: 127522
Reputation: 53055
For the case where A and B are both integers, floating point types, or pointers:
while (a && b)
do when a
and b
are both integers, floating point types, or pointers?AKA: rules of int
egers or other numbers being cast to bool
s.
When a
and b
are both integers, floating point types, or pointers, writing while (a && b)
is equivalent to while ((bool)a && (bool)b)
, and whenever you cast an one of these types to a bool
, zero is false
and everything else is true
.
If (bool)a
is false (value zero), then it stops evaluating early, since certainly a && b
cannot be true if the first part of that test is false.
This concept applies to if
, for
, while
, and do { } while
blocks, not just while
. It applies to !
, ||
, and &&
operators. The operands in such expressions are "said to be contextually converted to bool".
See here:
if
, while
, for
!
, &&
and ||
? :
static_assert()
declarationnoexcept
specifierexplicit
specifier (since C++20)while (a && b)
is exactly equivalent to while ((bool)a == true && (bool)b == true)
, which is also exactly equivalent to while (a != 0 && b != 0)
or (same thing): while (a != false && b != false)
.
Those can be read as: "while integers, floating point types, or pointers a and b are both true when cast to bool", or as: "while integers, floating point types, or pointers a and b are both non-zero."
I think most people prefer the while (a && b)
form, however, since it's the shortest and still easy to read.
The key takeaway is:
These all mean and do the same thing:
int a = 2;
int b = 3;
// // or
// float a = 2.0;
// float b = 3.0;
// // or
// int* a = (int*)0x11223344UL;
// int* b = (int*)0xaabbccddUL;
// // etc.
// these are all **equivalent**!:
// 1. "true"-based forms
while (a && b) {}; // shortest and most-often used version
while ((bool)a && (bool)b) {}; // most-explicit and clear version
while ((bool)a == true && (bool)b == true) {};
while (((bool)a == true) && ((bool)b == true)) {};
// 2. "false"-based forms (these all are exactly equivalent to the "true"-based
// forms above)
while (a != 0 && b != 0) {};
while ((a != 0) && (b != 0)) {};
while (a != false && b != false) {};
// etc.
The following, however, are NOT the same as the examples above:
while (a == true && b == true) {};
while ((a == true) && (b == true)) {};
This is because true
is defined strictly as 1
(and false
is defined strictly as 0
). Therefore, even though a == 1
is false when a
is 2
, (bool)a == 1
is true when a
is any non-zero integer, including 2
.
Note: this answer has been completely rewritten and fixed for correctness, and moved to here from this now-deleted question here: What does while (a && b)
do when a
and b
are both integers? [duplicate]. That question was deleted under the premise it was a duplicate of this question, hence why I moved my answer to here.
Upvotes: 0
Reputation: 1
Even in python short circuiting happens
a = []
if 0 and a[0]: # short circuit happens
print("short circuit")
if 1 and a[0]: # we get IndexError: list index out of range exception
print("this will not be evaluated")
Upvotes: -2
Reputation: 9
i will try to clear it as much as possible consider this below example:
#include <stdio.h>
void main()
{
int a= 1;
int b = 0;
if(a && b++)
printf("%d %d",a++,b);
printf("%d %d",a,b);
}
Output 1 1
now the same code with a = 0;
#include <stdio.h>
void main()
{
int a= 0;
int b = 0;
if(a && b++)
printf("%d %d",a++,b);
printf("%d %d",a,b);
}
Output : 0 0
as you can clearly see inside a if condition with &&(and) operation if the first argument is 0 then no matter what the value of b is this condition will fail so the second operator b wont even get executed.
with that being said if instead of && we kept ||(OR) then the result would be diff
#include <stdio.h>
void main()
{
int a= 0;
int b = 0;
if(a || b++)
printf("%d %d",a++,b);
printf("%d %d",a,b);
}
Output: 0 1
because now even though a was 0 there is still a chance be could be 1 and thus the compiler executes the line.
Upvotes: -1
Reputation: 9
for logical && both the parameters must be true , then it ll be entered in if {} clock otherwise it ll execute else {}. for logical || one of parameter or condition is true is sufficient to execute if {}.
if( (A) && (B) ){
//if A and B both are true
}else{
}
if( (A) ||(B) ){
//if A or B is true
}else{
}
Upvotes: -1
Reputation: 10502
Yes, it is called Short-circuit Evaluation.
If the validity of the boolean statement can be assured after part of the statement, the rest is not evaluated.
This is very important when some of the statements have side-effects.
Upvotes: 4
Reputation: 90042
You are asking about the &&
operator, not the if
statement.
&&
short-circuits, meaning that if while working it meets a condition which results in only one answer, it will stop working and use that answer.
So, 0 && x
will execute 0
, then terminate because there is no way for the expression to evaluate non-zero regardless of what is the second parameter to &&
.
Upvotes: 12
Reputation: 684
yes, if( (A) && (B) ) will fail on the first clause, if (A) evaluates false.
this applies to any language btw, not just C derivatives. For threaded and parallel processing this is a different story ;)
Upvotes: -6
Reputation: 200916
In C and C++, the &&
and ||
operators "short-circuit". That means that they only evaluate a parameter if required. If the first parameter to &&
is false, or the first to ||
is true, the rest will not be evaluated.
The code you posted is safe, though I question why you'd include an empty else
block.
Upvotes: 51