What should be the output of this C program?
#include<stdio.h>
int main(){
int x,y,z;
x=y=z=1;
z = ++x || ++y && ++z;
printf("x=%d y=%d z=%d\n",x,y,z);
return 0;
}
The given output is :
x=2 y=1 z=1
I understand the output for x, but fail to see how y and z values don't get incremented.
This is a result of short-circuit evaluation.
The expression ++x evaluates to 2, and the compiler knows that 2 || anything always evaluates to 1 ("true") no matter what anything is. Therefore it does not proceed to evaluate anything and the values of y and z do not change.
If you try with
x=-1;
y=z=1;
You will see that y and z will be incremented, because the compiler has to evaluate the right hand side of the OR to determine the result of the expression.
Edit: asaerl answered your follow-up question in the comments first so I 'll just expand on his correct answer a little.
Operator precedence determines how the parts that make up an expression bind together. Because AND has higher precedence than OR, the compiler knows that you wrote
++x || (++y && ++z)
instead of
(++x || ++y) && ++z
This leaves it tasked to do an OR between ++x and ++y && ++z. At this point it would normally be free to select if it would "prefer" to evaluate one or the other expression first -- as per the standard -- and you would not normally be able to depend on the specific order. This order has nothing to do with operator precedence.
However, specifically for || and && the standard demands that evaluation will always proceed from left to right so that short-circuiting can work and developers can depend on the rhs expression not being evaluated if the result of evaluating the lhs tells.
In C, any thing other than 0 is treated as true, And the evaluation for the || start from left to right.
Hence the compiler will check first left operand and if it is true then the compiler will not check other operands.
ex. A || B - In this case if A is true then compiler will return true only, and will not check whether B is true or False. But if A is false then it will check B and return accordingly means if B is true then will return true or if B is false then it will return false.
In your program compiler first will check ++x(i.e 2) and anything other than 0 is true in C. Hence it will not check/increment other expressions.
Related
#include <stdio.h>
int main()
{
int x, y, z;
x=y=z=1;
z = ++x || ++y && ++z;
printf("%d, %d, %d", x, y,z);
return 0;
}
I am getting output 2, 1, 1. I need and explanation why Y is 1 in output?
The || operator is short-circuiting; the right operand is not evaluated (and side effects never executed, i.e. the variables never incremented) if the left operand evaluates to != 0.
(Remember that "multiplication comes before addition", or in boolean logic AND comes before OR. Because of the operator precedences the expression becomes, fully bracketed, (++x) || ((++y) && (++z)); in other words, everything to the right of || is the OR's ignored right hand side.)
The evaluation of the left operand ++x increments x to 2. z is assigned the boolean value of the result of || which is 1, as it was all along.
As an aside, gcc warned and I think it is true that the statement is also undefined behavior. The C 11 standard draft n1570 says in 6.5/2:
If a side effect on a scalar object is unsequenced relative to [...]
a value computation using the value of the same scalar
object, the behavior is undefined.
The standard gives the example of i = ++i + 1; for this. In your right hand side expression z plays that role. The side effect is the increment, the value computation is the && sub-expression.
1 It is possible (i.e. I'm not sure) that it is defined as long as the right hand side is never evaluated. In that case the compiler would be allowed to assume that ++x is never 0 and omit the test. The generated code for the complicated boolean expression would just boil down to an increment of x.
The part || ++y && ++z is not evaluated, because ++x is already true. See
Short circuit evaluation
The logical operation || is so-called "short-circuit" or "lazy" operation.
If the left operand of such an operator is evaluating to logical true or a non-zero, the right operand won't be evaluated.
So in your case:
z = ++x || ++y && ++z;
++x is evaluating to 2, making x equal 2. This is non-zero, so everything on the right side is not evaluated, so y and z are not incremented. And z is assigned by the result of the logical OR operation, i.e. 1. And this is what you see.
#include <stdio.h>
#include <string.h>
main()
{
int i=-1, j=-1, k=0, l=2,m;
m = i++&&j++&&k++||l++;
printf("%d%d%d%d%d", i, j, k, l, m);
}
Output:
00131
I am confused how the expression is getting evaluated.
All that really matters here is the ||. Since l++ evaluates to the boolean 1 (true), the entire statement is true. So m is 1, and the rest are just their original values plus one for the post increment after they are evaluated.
You're evaluating the boolean expression:
((-1 && -1) && 0) || 2
As an aside, your definition of main should be:
int main(void)
I presume your question is about which increments will actually occur.
&& and || (logical and and logical or) are "short-circuit" operations. They evaluate only enough of their arguments to determine whether they're true or false. Effectively, x && y can be treated as x ? y : 0 and x || y can be treated as x ? 1 : y
&& takes precedence over ||, so start by looking at i++ && j++ && k++. This starts by evaluating i++, returning -1 and setting i to 0. Since the returned value is true (nonzero), we continue by evaluating j++, which once again returns -1 (true) and increments j to 0. We still haven't proven the value of the &&, so we evaluate k++, which returns 0 (false) and increments k to 1. That false gives us a final anded value of false.
Now we proceed to the ||. Effectively, you now have false || l++. The false is not enough to determine the result of the or, so we evaluate l++. That returns 2 (true), while setting l to 3. That true forces the value of the ||, and the final value of the expression, to be true.
Note that if i, j, or k had started as 0 (false), the later increments would not have occurred, since short-circuit evaluation would have decided they weren't needed in order to produce a result. In general, mixing && or || with side effects is a bad idea for exactly this reason -- it produces logic that is needlessly hard to understand. The ?: versions -- or a real if/then/else statement -- would make this interaction much, much clearer. You should understand how to read this sort of mess, because you will run into it in other programmers' C code -- but you should almost never write it. And if you must, you should document it to death. The sanity you save may be your own.
use this rules:
i++ =post increments the value of i, k++ =post increments the value of k, l++ =post increments the value of l, j++ =post increments the value of j
&& - if values compared are both nonzero true(1) otherwise false(0)
|| - if values compared are both zero false(0) otherwise true(1)
then apply towards expression m (also read on operator precedence in c)
I don't know if anyone could kindly explain this code for me?
unsigned int x = 0;
(x ^= x ) || x++ || ++x || x++;
printf("%d\n", x);
when I compile this on my computer using gcc 4.2, the output is 2.
Originally i thought maybe this behavior is unspecified but then i figure || will have lower precedence over other operators, so shouldn't the answer be 3? Since there are three "++".
Can someone explain? Thanks
(x ^= x) is evaluated and it yields 0, therefore:
(x++) is evaluated and it yields 0, therefore:
(++x) is evaluated and it yields 2, therefore it stops
It all boils down to one rule: || only evaluates its right side if its left side is false.
The issue is that the || operator is short-circuiting. As soon as it finds a true value, it no longer needs to check the remaining || statements; the answer is already known.
(x ^= x) evaluates to 0.
x++ evaluates to 0, then increments x to 1.
++x evaluates to 2 -- true.
The final or statement does not need to be computed. It "short-circuits" and immediately returns true.
The behaviour is well-defined. You are observing the short-circuiting behaviour of ||; the final x++ is never evaluated.
That is short-circuit semantics in action. The first expression x ^= x evaluates to 0, the second evaluates to 0 as well. The third one evaluates to 2, and then the logical expression is short-circuited since its result its already determined to be true.
Of course you shouldn't use such constructs, but let us analyze the expression.
There are 4 expressions combined with shortcut-OR:
a || b || c || d
b, c and d are only evaluated, if a is false, c and d only if b is false too, and d only if all from the before are false.
Ints are evaluated as 0 == false, everything else is not false.
x ^= 0
with x being 0 is 0 again.
x++
is evaluated and later increased, so it evaluates to 0, which invokes expression c, but later x will be increased.
++x
is first incremented, leading to 1, and then evaluated (leading to 1) which is the reason, why d is not evaluated, but the increment of b is pending, so we get 2.
But I'm not sure, whether such behaviour is exactly defined and leads to the same result on all compilers.
Avoid it.
The expressions between the || operators will be evaluated left to right until one is true:
(x ^= x )
Sets all bits in x to 0/off. (false);
x++
Increments x, it's now 1, but still false because this was a post increment.
++x
(pre-)Increments x, which is now 2 and also true, so there is no need for the right hand side of || to be evaluated.
This question already has answers here:
Why does "++x || ++y && ++z" calculate "++x" first, even though operator "&&" has higher precedence than "||"
(11 answers)
Closed 4 years ago.
The O/p comes out to be x=2,y=1,z=1 which doesnt agree with the operator precedence. I was running this on Turbo c++ compiler:
void main()
{
int x,y,z,q;
x=y=z=1;
q=++x || ++y && ++z;
printf("x=%d y=%d z=%d",x,y,z);
}
Actually the result is in complete accordance with standard C. The logical or operator (||) short circuits after ++x because it evaluates to a non-zero number, so the rest of them are ignored.
So starting at x=1, y=1, z=1, after the short circuit, you get x=2, y=1, z=1.
Operator precedence does not in any way determine the order in which the operators are executed. Operator precedence only defines the grouping between operators and their operands. In your case, operator precedence says that the expression
q = ++x || ++y && ++z
is grouped as
q = ((++x) || ((++y) && (++z)))
The rest has absolutely nothing to do with operator precedence at all.
The rest is determined by the semantics of each specific operator. The top-level operator in this case is ||. The specific property of || operator is that it always evaluates its left-hand side first. And if the left-hand size turns out to be non-zero, then it does not even attempt to evaluate the right-hand side.
This is exactly what happens in your case. The left-hand side is ++x and it evaluates to a non-zero value. This means that your whole expression with the given initial values is functionally equivalent to a mere
q = (++x != 0)
The right-hand side of || operator is not even touched.
x=y=z=1;
Makes all the variables = 1
q=++x || ++y && ++z;
Since ++x makes it = 2 and since it is not zero it stops checking the other conditions because the first one is true.
Thus, x=2, and y and z = 1
Logical && (AND) and || (OR) operators are subject to Short-Circuit.
"Logical operators guarantee evaluation of their operands from left to right. However, they evaluate the smallest number of operands needed to determine the result of the expression. This is called "short-circuit" evaluation."
Thus, for logical operators always evaluated as (no matter || or &&) left to right.
And as previously mentioned, precedence here only determines who takes who.
Then left to right rule;
q = ++x || ++y && ++z;
//ok, lets play by rule, lets see who takes who:
//first pass ++ is badass here (has highest precedence)
//q = (++x) || (++y) && (++z)
//second pass &&'s turn
//q = (++x) || ((++y) && (++z))
//done, let's do left to right evaluation
q = (++x) || rest..
q = (true)|| whatever..
hope that helps more clear.
Why does this code always produce x=2?
unsigned int x = 0;
x++ || x++ || x++ || x++ || ........;
printf("%d\n",x);
the 1st x++ changes x to 1 and returns 0
the 2nd x++ changes x to 2 and returns 1
at which point the or short circuits, returns true, and leaves x at 2.
x++ || x++ || x++ || x++ || ........;
First x++ evaluates to 0 first for the conditional check, followed by an increment. So, first condition fails, but x gets incremented to 1.
Now the second x++ gets evaluated, which evaluates to 1 for the conditional check, and x gets incremented to 2. Since expression evaluates to 1 (true), there's no need to go further.
Because of short circuit in boolean expression evaluation and because || is a sequence point in C and C++.
|| short-circuits. Evaluated from left, when a true value is found (non-zero) it stops evaluating, since the expression now is true and never can be false again.
First x++ evaluates to 0 (since it's post-increment), second to 1 which is true, and presto, you're done!
When you're evaluating "a || b || c || d || e || ..." you can stop evaluating at the first non-zero value you find.
The first "x++" evaluates to 0, and increments x to 1, and evaluating the expression continues. The second x++ is evaluated to 1, increments x to 2, and at that point, you need not look at the rest of the OR statement to know that it's going to be true, so you stop.
Because logical OR short-circuits when a true is found.
So the first x++ returns 0 (false) because it is post-increment. (x = 1)
The second x++ returns 1 (true) - short-circuits. (x = 2)
Prints x = 2;
Because of early out evaluation of comparisons.
This is the equivalent of
0++ | 1++
The compiler quits comparing as soon as x==1, then it post increments, making x==2
Because the first "x++ || x++" evaluates to "true" (meaning it is non zero because "0 || 1" is true. Since they are all logical OR operators the rest of the OR operations are ignored.
Mike
The || operator evaluates the left-hand expression, and if it is 0 (false), then it will evaluate the right-hand expression. If the left hand side is not 0, then it will not evaluate the right hand side at all.
In the expression x++ || x++ || x++ || ..., the first x++ is evaluated; it evaluates to 0, and x is incremented to 1. The second x++ is evaluated; it evaluates to 1, and x is incremented to 2. Since the second x++ evaluated to a non-zero value, none of the remaining x++ expressions are evaluated.
trying replacing || with |.--
It is the short circuiting of logical operators.
It's the same reason when you do
if (returns_true() || returns_true()){ }
returns_true will only get called once.