Precedence only controls the grouping of operators with operands, not the order in which expressions are evaluated.
The side effect of the ++
operator does not have to be applied immediately after evaluation, it only needs to be applied before the next sequence point.
Edit
You can certainly look at the generated assembly code to see how your compiler handled that particular case, just be aware that depends on the code and how you compiled it (different levels of optimization will likely affect it).
With a few exceptions1, C does not require expressions to be evaluated in any particular order (left to right, right to left, or any other order). In this particular case, all that matters is that we’re comparing the result of obj->data + obj->data_size
to the result of obj->start_point++
. Any of the following orders of evaluation are possible:
Order 1
–––––––
tmp1 = obj->data + obj->data_size
result = obj->start_point >= tmp1
obj->start_point = obj->start_point + 1
Order 2
–––––––
tmp1 = obj->start_point
obj->start_point = obj->start_point + 1
tmp2 = obj->data + obj->data_size
result = tmp1 >= tmp2
Order 3
–––––—–
tmp1 = obj->start_point
tmp2 = obj->data + obj->data_size
obj->start_point = obj->start_point + 1
result = tmp1 >= tmp2
Or something else completely.
The evaluations of obj->start_point++
and obj->data + obj->data_size
can even be interleaved with each other - after all, each of obj->start_point
, obj->data
, and obj->data_size
are expressions that need to be evaluated as well.
As long as the result is correct - we are comparing the result of the postfix ++
operator on obj->start_point
to the result of the addition of obj->data
and obj->data_size
- the compiler has a lot of freedom in how it orders the evaluation of each subexpression, and that order does not have to be consistent over the entire program (a similar expression elsewhere in the same program may be evaluated differently).
Answering leoleohu's question from the comments
leoleohu asks
But my question is still there, who decides postfix ++ is conducted after >=, and prefix ++ is conducted before >=?
It's up to the compiler, and it doesn't have to be the same for every expression in the same code.
The ++
and --
operators, both prefix and postfix forms, have a result and a side effect.
The result of obj->start_point++
is the current value of obj->start_point
. The side effect is to add 1 to obj->start_point
. In the expression
obj->start_point++ >= obj->data + obj->data_size
the result of obj->start_point++
(the current value of obj->start_point
) is compared to the result of obj->data + obj->data_size
.
The side effect of adding 1 to obj->start_point
can happen at any point after evaluation, as long as it occurs before the next sequence point. It can be applied before or after the comparison - the compiler is free to make that decision based on considerations like current level of optimization, other operands in the expression, surrounding code, etc.
- The
&&
, ||
, ?:
, and comma operator (which is not the same thing as the comma that separates arguments in a function call) all force left-to-right evaluation.