I wrote the following code:
int 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);
i=-1,j=-1,k=0,l=2,m;
m = ++i && ++j && ++k || ++l;
printf("\n%d %d %d %d %d",i,j,k,l,m);
return(0);
}
and i got the following result:
0 0 1 3 1
0 -1 0 3 1
as i know postfix and prefix operators are solved after the semicolon,ie. the original values are used in the expression and then the variables resolve themselves. In that case
i++ && j++
should be equal to
++i && ++j
and both should be equivalent to
i && j;
i = i+1;
j = j+1;
and hence the result for the two expressions must be same. but it is not so. please anyone can help me with where do i have a wrong concept.
i++ && j++
is definitely not equivalent to ++i && ++j
.
Take the case where both are zero - the first results in:
0 && j++
yielding a 0 result (and because of short-circuiting, j won't even get incremented).
In the second case, you'll get
1 && 1
yielding a 1 result.
With that in mind, let's look at your examples (spaces, semicolons and newlines added for readability):
First up:
int i = -1;
int j = -1;
int k = 0;
int l = 2;
int m = i++ && j++ && k++ || l++;
Let's first parenthesize completely to make it easier to deal with:
int m = ((i++ && j++) && k++) || l++;
So, what's going to happen? First, the i++
. i
is incremented (and becomes 0
), but because it's a post-increment, the expression's result is -1
. That gives:
int m = ((-1 && j++) && k++) || l++;
Since the left side of that &&
is non-zero, the right side is evaluated. j++
increments j
to 0
, but again, post-increment means the expression's value is -1
.
int m = ((-1 && -1) && k++) || l++;
Resolve that &&
:
int m = (1 && k++) || l++;
Next, the right side of the remaining &&
. k
is incremented, becoming 1
, but the expression yields 0
:
int m = (1 && 0) || l++;
Resolve this &&
:
int m = 0 || l++;
And finally, because the left side of the ||
is 0, the right side is evaluted. l
is incremented, becoming 3
, but as a post-increment, yields 2
:
int m = 0 || 3;
Finally:
int m = 1;
And along the way we ended up with:
i = 0;
j = 0;
k = 1;
l = 3;
Explaining your first printout.
Next, let's look at the second example (more condensed; let me know if you want more details):
int i = -1, j = -1, k = 0, l = 2, m;
m = ((++i && ++j) && ++k) || ++l; // parenthesized for readability
^ // i is pre-incremented
m = (( 0 && ++j) && ++k) || ++l;
^ // first && operator short-circuits
m = (0 && ++k) || ++l;
^ // second && operator short-circuits
m = 0 || ++l;
^ // l is pre-incremented
m = 0 || 3;
^ // evaluate || operator
m = 1;
The results are:
i = 0
j = -1
k = 0
l = 3
m = 1
Exactly what you saw printed out.