Short circuit evaluation with both && || operator - c

I know what is short circuit evaluation in C.
a && b (operand b is not checked if a = 0)
a || b (operand b is not checked if a = non zero)
But I am stuck at this question
int x = 0;
if (5 || 2 && ++x)
printf("%d", x);
This outputs 0.
My first thinking goes as follows:
According to precedence table , precedence is ++, &&, || (descending order)
++x: evaluated.x becomes 1.
2 && ++x evaluated. Both operands are evaluated.
|| is evaluated.
But according to this, 1 should be printed, not 0.
My second thinking goes as this:
5 || anything
anything is not evaluated because of short circuit evaluation, so no precedence comes into play here.

The expression 5 || 2 && ++x is equivalent to 5 || (2 && ++x) due to operator precedence.
The run time evaluates the expression 5 || 2 && ++x from left to right.
As we know in OR if first condition is true it will not check the second condition.
So here 5 evaluated as true and so (2 && ++x) will not be performed.
That's why x will remain 0 here.

Correct. The expression is short circuited. You can test it with this.
if(5 || ++x) {
printf("%d\n",x);
}

Related

What is the output of this program

Please explain output of this program.
#include<stdio.h>
int main()
{
int x=0;
x ^= x || x++ || ++x || x++;
printf("\n%d",x);
}
O/p is 3 (http://codepad.org/X49j0etz)
According to me output should be 2.
as || is a sequence point as far as i remember.
so expression becomes.
x ^= 0 || 0 || 2 || 2;
so after evaluation of this expression(x || x++ || ++x || x++;) x becomes 3
x = 3 ^ 1
so x becomes 2;
I'm pretty sure the answers claiming undefined behaviour are correct, but there is also a simple explanation for how you can arrive at the result of 3.
Just consider that the last x++ is never evaluated because the last || operation short-circuits, and let's assume that the side effects are applied before the ^= is evaluated. Then you are left with
x = 2 ^ 1;
Unsurprisingly resulting in 3.
This is an undefined behavior in c. Because we cannot predict in which direction the expression is evaluated

Output of following code [duplicate]

This question already has answers here:
Why isn't "k" incremented in the statement "m = ++i && ++j || ++k" when "++i&&++j" evaluates to true? [duplicate]
(5 answers)
Closed 9 years ago.
#include<stdio.h>
int main()
{
int i=-3,j=2,k=0,m;
m= ++i && ++j || ++k;
printf("%d %d %d %d",i,j,k,m);
return 0;
}
Could someone tell how does is the m evaluated. I am confused as how k remain '0'
m= ++i && ++j || ++k;
First, ++i && ++j takes effect, i become -2 and j become 3, which makes ++i && ++j non-zero, so m will be evaluated to 1 (true) because of short-circuit. All the later expression(++k) won't be executed.
m= ( (++i) && (++j) ) || ++k;
| |
| |
( T (-2) AND T(3) ) OR something
^^^^^^^^^^^^^^^^^
T OR something
^^^^^^^^^^^^^^^^^^^^^^^^^
= T
= 0
Changing j=-1
m= ( (++i) && (++j) ) || ++k;
| |
| |
( T (-2) AND T(0) ) OR something
^^^^^^^^^^^^^^^^^
F OR T (0) //++k evaluated
^^^^^^^^^^^^^^^^^^^^^^^^^
= T
= 0
Initialized Values:
int i=-3,j=2,k=0,m;
Original expression:
m= ++i && ++j || ++k;
With implicit operator precedence:
m= (++i && ++j) || ++k;
The expression evaluates left to right. What you need to understand is how Short Circuit Logic works.
Evaluation Walkthrough:
i gets incremented (-3 --> -2)
The logical AND operator is evaluated (&&). It checks if the left hand argument i evaluates to true (i!=0). If the left hand side evaluates to false, the and operator short circuits the evaluation and returns false (0). This doesn't happen because i==-2, so the right hand side (++j) is also evaluated.
j get incremented (2 --> 3)
Logical AND finishes its right hand side evaluation i!=0 && j!=0. It returns true (!0).
The logical OR operator is evaluated (||). It checks if the left hand argument (++i && ++j) evaluates to true (!0). If the left hand side evaluates to true, the and operator short circuits the evaluation and returns true (!0). This happens because ++i && ++j already evaluated true. Consequent k++ never executes!
Logical OR (||) assigns the evaluated value (!0) to m. m!=0 after the expression evaluates.
This is because of short circuting. If you know about how an OR expression is evaluated, you will get the hang of this expression. 1 OR Anything is always 1
int i=-3,j=2,k=0,m;
m= ++i && ++j || ++k;
`-2 && +3 is +1 therefore +1 OR anything is 1.` Hence C skips evaluation of k.
the answer would be
-2 3 0 1
Explanation :
There are two basic facts that work here
FACT 1 :
Whenever there is an expression with PRE-INCREMENT operator, All these operators would be operated on the corresponding variables first, and then the whole expression would be evaluated with updated values of variables.
FACT 2
whenever there is an expression having OR operator, If first operator is true(or non zero in some cases), second operator wouldn't be executed.
for example
a=2;
b=2;
c=3;
boolean k = c || a+b ;
The values of variable k would be true and the expression "a+b" wouldn't be even considered as c is non zero.
In your case variable i and j would be incremented first and the expression would be
-2 && 3 || ++k
Note : variable k wouldn't be incremented here because in case of OR logical operator Left operand would be solved completely first.
Left operand would would be then TRUE because both -2 and 3 are non zero .
so the whole expression would be
TRUE || ++k
This wouldn't be evaluated further because no matter what, the result always be TRUE .
as we are assigning this result (TRUE) to an integer variable, it would be 1.
Hence the answer is ....

Increment operator in C

I tried the following code snippet:
void main()
{
int x = 1,y = 1,z = 1;
++x || ++y && ++z;
printf("x = %d\ny = %d\nz = %d\n",x,y,z);
}
The output I expected was:
x = 2
y = 2
z = 2
But I am getting the output:
x = 2
y = 1
z = 1
What is the reason for this?
This is because of short-circuiting.
http://en.wikipedia.org/wiki/Short-circuit_evaluation
When this is evaluated:
++x || ++y && ++z;
The first part ++x already determines the value of the entire expression. So the ++y && ++z is not executed at all. So the side-effects of ++y and ++z are not invoked.
The result of ++x is nonzero, so evaluates to true, so short-circuits the || operator. ++y && ++z is not executed.
The reason is you're using Brobdingnagian boolean expressions with side effects.
The operators && and || are "short-circuiting". That means if the result of the expression is determined after the left operand is evaluated, the right operand never gets evaluated.
Avoid using expression with side-effects as operands of boolean operators. Even if the behaviour is what you want.

Operator precedence in C [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
why "++x || ++y && ++z" calculate "++x" firstly ? however,Operator "&&" is higher than "||"
The following program does not seem to work as expected. '&&' is to have higher precendence than '||', so the actual output is confusing. Can anyone explain the o/p please?
#include <stdio.h>
int main(int argc, char *argv[])
{
int x;
int y;
int z;
x = y = z = 1;
x++ || ++y && z++;
printf("%d %d %d\n", x, y, z);
return 0;
}
The actual output is: 2 1 1
TIA.
Precedence and order of evaluation have no relation whatsoever.
&& having higher precedence than || means simply that the expression is interpreted as
x++ || (++y && z++);
Thus, the left-hand operand of || is evaluated first (required because there is a sequence point after it), and since it evaluates nonzero, the right-hand operand (++y && z++) is never evaluated.
The confusing line is parsed as if it were:
x++ || (++y && z++);
Then this is evaluated left-to-right. Since || is a short-circuit evaluator, once it evaluates the left side, it knows that the entire expression will evaluate to a true value, so it stops. Thus, x gets incremented and y and z are not touched.
The operator precedence rules mean the expression is treated as if it were written:
x++ || (++y && z++);
Since x++ is true, the RHS of the || expression is not evaluated at all - hence the result you see.

Please explain an apparent conflict between precedence of && and || and the actual result of an expression [duplicate]

This question already has answers here:
Precedence of && over || [duplicate]
(4 answers)
Closed 8 years ago.
I don't understand the output of the following program:
#include<stdio.h>
int main()
{
int i=-3, j=2, k=0, m;
m = ++i || ++j && ++k;
printf("%d %d %d %d\n", i, j, k, m);
return 0;
}
The output is -2 2 0 1 instead of -2 3 1 1, implying that ++i was evaluated (and caused the || operator to short-circuit its right hand side) before the expression ++j && ++k which appears to contradict the fact that the && operator has higher precedence than ||.
Would someone explain why?
The output should be something like:
Error, line 2: 'm': undefined variable.
Edit: with that fixed, only the ++i should be evaluated. Precedence does not determine (or even affect) order of evaluation. Precedence means the expression is equivalent to ++i || (++j && ++k). Order of evaluation for || or && is always that the left operand is evaluated, then there's a sequence point. After the sequence point, the right operand is evaluated if and only if necessary to determine the final result (i.e., the right operand of || is evaluated if the left operand evaluated to zero; the right operand of && is evaluated if the left operand evaluated to non-zero).
In this expression, ++i is evaluated, then because it's the left operand of || and evaluated non-zero, none of the rest of the expression is evaluated.
-2 2 0 1
Lazy.
#include <stdio.h>
int main()
{
int i=-3,j=2,k=0;
int m=++i||++j&&++k;
printf("%d %d %d %d",i,j,k,m);
}
Compile, run and see for youself.
gcc tmp.c -o tmp
The expression:
++i || ++j && ++k
Is equivalent to:
(++i) || ((++j) && (++k))
Explaining:
++i is evaluated -- (-2) || ((++j) && (++k));
The || operator is evaluated -- (1);
Since 1 || anything evalutes true, the right operand is not evaluated. Thus, the && precedence doesn't matter here. This short circuiting is guaranteed in both C and C++ by the relevant standards (see Is short-circuiting logical operators mandated? And evaluation order?).
Now, try using a sub-expression, like this:
(++i || ++j) && ++k
Which is equivalent to:
((++i) || (++j)) && (++k)
Explaining:
++i is evaluated -- ((-2) || (++j)) && (++k);
|| is evaluated -- (1) && (++k)
++k is evaluated -- (1) && (1);
Evaluates true;
By way of explanation:
#include <stdio.h>
int main()
{
if (-1)
printf ("-1!\n");
else
printf ("Not -1.\n");
return 0;
}
Negative numbers are not false in C. Always compare boolean values to 0 (or FALSE) or you can get bitten by if (worked == TRUE) giving false negatives.

Resources