Wojtek Lerch said:
Is it? I've always believed that an assignment operator returns the value
that it also stores in the object, *without* reading it back from the
object, and that the Standard's description in terms of "the value of the
object after the assignment" was just a clumsy wording (no offense) that
wasn't meant to imply a read access.
I agree.
I think a "read" access to an object involves a lvalue-to-value
conversion (6.3.2.1-1), even though that's not clearly stated.
Moreover 6.5.16-3 indicates that assignment expressions aren't lvalues.
They have the value (rvalue) of the left operand after the assignment.
I think it implies that a volatile variable is not read twice.
Note that this is different from C++ where assignments are lvalues
which makes
int a,b,c=0;
a=b=c;
Well-defined in C but undefined in C++ (I think it's a C++ standard
defect but fortunately not a C defect).
I can think of an hypotetical implementations giving strange behavior
to a[0]=0;a[a[0]]=1;
#include <stdio.h>
int main(void) {
int a[3];
a[0]=0; /* line 1 */
a[a[0]]=1; /* line 2 */
printf("%d\n", a[0]); /* line 3 */
return 0;
}
The C implementation may notice that a[0] is read on line 3 and
assigned a constant value on line 2, and so, its
constant-value-optimization module may test if the value of a[0] may have been
modified between line 1 and line 3. If it proves it cannot be modified,
it will be able to optimize the printf statement to:
printf("%d\n", 0);
Now, the C implementation analyzes line 2. It notices that the a array
is written, but, due to the fact a[0] is read for something that's not
needed to compute the value (the 1 literal), it cannot be
modified before the next sequence point (at end of this statement).
Thus, the compiler may optimize the printf statement, and output zero.
As n1124 is worded, this optimization is legal.