Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

assignment expressions and volatile

Tags:

c

volatile

I seem to have a reasonable understanding of volatiles in general, but there's one seemingly obscure case, in which I'm not sure how things are supposed to work per the standard. I've read the relevant parts of C99 and a dozen or more related posts on SO, but can't find the logic in this case or a 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; */

Should a be evaluated like this:

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

or like this:

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

?

Similarly, should c be evaluated like this:

  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 like a = b; c = b; things are clear. But how about the ones above?

Basically, the question is, what exactly does "expression has the value of the left operand after the assignment" mean in 6.5.16c3 of C99 when the object is volatile?:

An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue.

Does it imply an extra read of the volatile to produce the value of the assignment expression?

UPDATE:

So, here's the dilemma.

If "the value of the object after the assignment" is not obtained from the extra read of the volatile object, then the compiler makes the assumption that the volatile object b:

  • is capable of holding an arbitrary int value that gets written into it, which it may not be (say, bit 0 is hardwired to 0, which is not an unusual thing with hardware registers, for which we are supposed to use volatiles)
  • cannot change between the point when the assigning write has occurred and the point when the expression value is obtained (and again it can be a problem with hardware registers)

And because of all that, the expression value, if not obtained from the extra read of the volatile object, does not yield the value of the volatile object, which the standard claims should be the case.

Both of these assumptions don't seem to fit well with the nature of volatile objects.

If, OTOH, "the value of the object after the assignment" is obtained from the extra implied read of said volatile object, then the side effects of evaluating assignment expressions with volatile left operands depend on whether the expression value is used or not or are completely arbitrary, which would be an odd, unexpected and poorly documented behavior.

like image 200
Alexey Frunze Avatar asked Oct 23 '22 08:10

Alexey Frunze


1 Answers

C11 clarifies that this is unspecified.

You can find the final draft of C11 here. The second sentence you quoted now refers to footnote 111:

An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment,111) but is not an lvalue.

Footnote 111 says this:

  1. The implementation is permitted to read the object to determine the value but is not required to, even when the object has volatile-qualified type.
like image 68
rob mayoff Avatar answered Oct 27 '22 00:10

rob mayoff