Why is "if (i++ && (i == 1))" false where i is an int holding the value 1?
No. In C, there's a sequence point between the evaluation of the LHS of the &&
operator and the evaluation of the RHS, and the increment must take place and be completed before the RHS is evaluated. So, the i++
(equivalent to i++ != 0
) is executed and the increment is completed (and the expression evaluates to true), so by the time the RHS is evaluated, i == 2
and hence the overall expression is false and you get 'No' printed. If the LHS of the &&
operator evaluated to false (0), the RHS would not be evaluated because of the 'short-circuit' property of the &&
operator.
Only a few operators have the property of having a sequence point between the evaluation of the LHS and RHS: &&
, ||
, and ,
(as an operator, not as a separator in an argument list) — and there's ? :
too, which isn't a binary operator but which has a sequence point after the condition is evaluated and before either the expression after the ?
or the expression after the :
is evaluated (of which one or the other, but not both, is always evaluated).
The &&
and ||
operators are the only operators with the 'short-circuit' property. The RHS of &&
is only evaluated if the LHS evaluates to true; the RHS of ||
is only evaluated if the LHS evaluates to false.
Clarification on Sequence Points
Iwillnotexist Idonotexist correctly asserted:
The C11 standard hasn't done away with sequence points, only the C++11 standard did.
C++11 (ISO/IEC 14882:2011) says:
1.9 Program execution
¶13 Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread (1.10), which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced. [Note: The execution of unsequenced evaluations can overlap. —end note] Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which. [Note: Indeterminately sequenced evaluations cannot overlap, but either could be executed first. —end note]
The term 'sequence point' does not appear in C++11 at all (the only near match is 'sequence pointer').
C11 (ISO/IEC 9899:2011) says:
5.1.2.3 Program execution
¶3 Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread, which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. (Conversely, if A is sequenced before B, then B is sequenced after A.) If A is not sequenced before or after B, then A and B are unsequenced. Evaluations A and B are indeterminately sequenced when A is sequenced either before or after B, but it is unspecified which.13) The presence of a sequence point between the evaluation of expressions A and B implies that every value computation and side effect associated with A is sequenced before every value computation and side effect associated with B. (A summary of the sequence points is given in annex C.)
13) The executions of unsequenced evaluations can interleave. Indeterminately sequenced evaluations cannot interleave, but can be executed in any order.
So, C11 does retain sequence points, but adds the 'sequenced before' and related terms using essentially the same terminology as C++11.
Here, a simple explanation
and that's why this condition becomes 'false'
When &&
is used in an expression, its arguments are guaranteed to be evaluated from left to right. So i
will have the value of 2
when (i==1)
is evaluated. Therefore, the expression is false, and the else
part will be executed.
However, note for completeness that if the left argument evaluates to false or 0, then the right argument is not evaluated at all.
I think 1&&1=1 and 1&&0=0 is clear to you. Michael L 's answer seems good to me.But still I will try to elaborate a little bit. Here is link which provides operator precedence list:
http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm
If you visit the this link and refer that table then you will come to know that && has left to right associativity.So first i will become 2 AFTER left part(Sruit tried to show this using diagram);then for right part i==1 checking is done.We can check this by writing the code like the one given below:
This code explains that i=2 when execution flow reaches i==1 part.
#include <stdio.h>
int main() {
int i = 1;
if (i++ && (printf("%d\n",i)))
printf("Yes\n");
else
printf("No\n");
return 0;
}
So the output is:
2
Yes
So 2==1 comes out to be false and ultimately the answer gives surprising feel!!! Right hand side bracket gives 0 and left side 1 so 1&&0=0. I think this is fair enough to understand.