It seems that I have a reasonable understanding of volatiles in general, but there is one seemingly obscure case in which I am not sure how everything should work on a standard. I read the relevant parts of C99 and a dozen or more related entries in SO, but cannot find the logic in this case or the place where this case is explained.
Suppose we have this piece of code:
int a, c; volatile int b; a = b = 1; c = b += 1;
If a will be evaluated as follows:
b = 1; a = b; // volatile is read
or like this:
b = 1; a = 1;
?
Similarly, if c will be evaluated as follows:
int tmp = b; tmp++; b = tmp; c = b;
or like this:
int tmp = b; tmp++; b = tmp; c = tmp;
?
In simple cases, such as a = b; c = b; a = b; c = b; , all clear. But what about the above?
Basically, the question is what exactly means that “the expression has the value of the left operand after assignment” means in 6.5.16c3 C99, when is the object mutable ?:
The assignment operator stores the value in the object indicated by the left operand. The expression has the value of the left operand after assignment , but is not an lvalue.
Does this imply extra reading volatile to get the value of the assignment expression?
UPDATE
So here is the dilemma.
If the "value of the object after assignment" is not obtained from an additional reading of the volatile object, then the compiler makes the assumption that the volatile object b :
- able to hold an arbitrary
int value, which is written into it, which may not be the case (for example, bit 0 is tied to 0, which is not unusual for hardware registers, for which we must use volatile). - cannot change between the point when the destination record occurred and the point when the value of the expression is received (and again this may be a problem with the hardware registers).
And because of all this, the value of the expression, if it is not obtained from an additional reading of the volatile object, does not give the value of the volatile object, which must meet the standard requirements.
Both of these assumptions seem to be inconsistent with the nature of mutable objects.
If OTOH, “the value of an object after assignment” is obtained from an additional implied reading of the said volatile object, then the side effects of evaluating assignment expressions with volatile left operands depend on whether the value of the expression is used or not or are completely arbitrary, which would be strange, unexpected and poorly documented behavior.