Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When are the ++c and c++ increments applied exactly here? [duplicate]

Just to see how much I understood how the ++c/c++ operator works, I tried to run these C programs:

int c = 5;
c = c - c++;
printf("%d\n", c);

prints 1, I guess the logic is that the ++ is applied after the line of code where it's used, so c becomes = c - c which is 0, and on the "next line" it's increased by one. But it seems strange to me, I'd like to know more in detail what should happen with regards to the operators priority.

Now on to this:

int c = 5;
c = c - ++c;
printf("%d\n", c);

this one prints 0, and I can't really understand why. If right hand values are parsed from left to right, I guess it would read c which is 5, then ++c which is 6 as it should be applied immediately. Or does it calculate the ++c before the whole right hand value calculation, so that it's actually doing 6 - 6 because the increment also involves the first calling of c?

like image 535
memememe Avatar asked Jan 26 '23 13:01

memememe


1 Answers

For C++ (all versions, explanation applies to C++11 and later):

Both have undefined behavior, meaning that not only is the value that it will return unspecified, but that it causes your whole program to behave in an undefined manner.

The reason for this is that evaluation order inside an expression is only specified for certain cases. The order in which expressions are evaluated does not follow the order in the source code and is not related to operator precedence or associativity. In most cases the compiler can freely choose in which order it will evaluate expressions, following some general rules (e.g. the evaluation of an operator is sequenced after the value computation of its operands, etc.) and some specific ones (e.g. &&'s and ||'s left-hand operands are always sequenced before their right-hand operands).

In particular the order in which the operands of - are evaluated is unspecified. It is said that the two operands are unsequenced relative to one another. This in itself means that we won't know whether c on the left-hand side of c - [...] will evaluate to the value of c before or after the increment.

There is however an even stricter rule forbidding the use of a value computation from a scalar object (here c) in a manner unsequenced relative to a side effect on the same scalar object. In your case both ++c and c++ cause side effects on c, but they are unsequenced with the use of the value on the left hand side of c - [...]. Not following this rule causes undefined behavior.

Therefore your compiler is allowed to output whatever it wants and you should avoid writing code like that.

For a detailed list of all the evaluation order rules of C++, see cppreference.com. Note that they changed somewhat with the different C++ versions, making more and more previously undefined or unspecified behavior defined. None of these changes apply to your particular case though.

like image 122
walnut Avatar answered Jan 29 '23 11:01

walnut