Assignment Expressions and Volatile

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; /* or equivalently c = ++b; */ 

If a will be evaluated as follows:

  b = 1; a = b; // volatile is read 

or like this:

  b = 1; a = 1; // volatile isn't read 

?

Similarly, if c will be evaluated as follows:

  int tmp = b; tmp++; b = tmp; c = b; // volatile is read 

or like this:

  int tmp = b; tmp++; b = tmp; c = tmp; // volatile isn't read 

?

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.

+3
c volatile
source share
1 answer

C11 clarifies that it is undefined.

Here you can find the final version of C11 here . The second sentence that you are quoting now refers to footnote 111:

The assignment operator stores the value in the object indicated by the left operand. The assignment expression has the value of the left operand after the assignment, 111) but is not the value of l.

Footnote 111 says the following:

111) Implementations are allowed to read an object to determine the value, but it is not required, even if the object has an unstable type.

+2
source share

All Articles