Reputation: 333
#define MAX(a,b) ((a)>(b) ? (a) : (b))
int main(void) {
int a=2;
int b=3;
int c = MAX(a++,b++); // c=((a++)>(b++) ? (a++) : (b++));
printf("\na= %d", a);// a=3
printf("\nb= %d", b);//b=5
printf("\nc= %d", c);//c=4
a=3;
b=2;
cc = MAX(a++,b++); // c=((a++)>(b++) ? (a++) : (b++));
printf("\na= %d", a); // a=5
printf("\nb= %d", b); //b=3
printf("\nc= %d", c); //c=4
return 0;
}
I would like to know why c
is not evaluating to 5.
It appears to me the evaluation order should be:
(a++)>(b++)
c=((a++)>(b++) ? (a++) : (b++))
, goes to (a++)
, so a
increments again.c
, then c
should have the greater value
twice-incremented, that is 5. However, I am getting 4. I suspect the
greater value's second increment is happening at the end, but I can't
explain why, since the parentheses seem to indicate that the
assignment comes at the end.Any idea?
Upvotes: 1
Views: 284
Reputation: 106
For a++ it's equivalent as saying
int temp = a;
a = a + 1;
return temp;
so in the case of a=2, b=3, we can go to the condition (a++)>(b++) and we can have a rewritten as
int temp1 = a;
a = a + 1;
return temp1;
and b rewritten as
int temp2 = b;
b = b + 1;
return temp2;
now since it's only a conditional statement, we're really just evaluating the old values of a and b before the increment which is temp1 = 2 and temp2 = 3 while at the same time a and b values have changed a = 3, b = 4. Since temp1 < temp2 from the old value, we go to the false clause of the ternary operator (b++) and do the same thing as we did before
int temp3 = b;
b = b + 1;
return temp3;
so now b is 5 while the returned temp3 is the previous value of b which is 4. Hope this helps!
Upvotes: 0
Reputation: 311108
Let's consider for example this declaration
int c = MAX(a++,b++);
after the macro substitution there will be
int c = (( a++) >( b++ ) ? (a++) : (b++));
The variables a
and b
are initialized like
int a=2;
int b=3;
As a
is less than b
then the third expression (b++)
will be evaluated as a result of the conditional operator. In the first expression ( a++) >( b++ )
a
and b
were incremented. There is a sequence point after the evaluation of the first expression.
So a
will be set to 3
, b
will be set to 4
.
As it was already said the value of the conditional operator is the value of the third expression (b++)
where there is used the post-increment. The value of the post-increment operator is the value of its operand before incrementing.
From the C Standard (6.5.2.4 Postfix increment and decrement operators)
2 The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it).
So the value of the conditional operator is 4
. This value will be assigned to the variable c
. But as a side effect the value of b
will be incremented.
Thus after this declaration a
will be equal to 3
, b
will be equal to 5
and c
will be equal to 4
.
For clarity this declaration
int c = (( a++) >( b++ ) ? (a++) : (b++));
in fact can be rewritten in the logically equivalent way.
int result = a > b;
++a;
++b;
int c;
if ( result != 0 )
{
c = a++;
}
else
{
c = b++;
}
Upvotes: 2
Reputation: 123578
The postfix ++
operator has a result and a side effect. The result of a++
is the value of a
before the increment - given
int a = 1;
int x = a++;
the value of x
will be 1
and the value of a
will be 2. Note that the side effect of adding 1
to a
does not have to be applied immediately after evaluation - it only has to be applied before the next sequence point.
So, looking at
((a++) > (b++)) ? (a++) : (b++)
The ?:
operator forces left-to-right evaluation, so the first thing that happens is that (a++) > (b++)
is evaluated1. Since a
is initially 2
and b
is initially 3
, the result of the expression is false (0
). The ?
operator introduces a sequence point, so the side effects to a
and b
are applied and a
is now 3
and b
is now 4
.
Since the result of the condition expression was 0
, we evaluate b++
. Same thing, the result of the expression is the current value of b
(4
), and that value gets assigned to c
. The side effect to b
is applied at some point, and by the time everything's finished, a
is 3
, b
is 5
, and c
is 4
.
a++
or b++
may be evaluated first, since the >
operator doesn't force left-to-right evaluation.
Upvotes: 2