A
André Gillibert
Wojtek Lerch said:It's the other way around: a lvalue-to-value conversion involves a read
access, but that doesn't mean that every read access is part of an
lvalue-to-value conversion.
Indeed, you're right.
However, the standard doesn't specify where there are no read access...
e.g.
int y=0;
volatile int x;
x=y;
The standard doesn't specify if y is to be read 153 times or only once.
Twice? This is about whether an assignment to a volatile variable reads
it *once* or not at all. I don't think anybody has claimed that it reads
is twice.
Excuse me... I had in mind the case of i = i + 1 where i is a volatile
variable.
It's undefined in C++? Why?
This has even been mentioned in a C++ DR (DR #222).
From http://std.dkuug.dk/JTC1/SC22/WG21/docs/cwg_active.html#222:
One could argue that as the C++ standard currently stands, the effect of x
= y = 0; is undefined. The reason is that it both fetches and stores the
value of y, and does not fetch the value of y in order to compute its new
value.
This DR also deals with volatile variable in assignments... In the context
of C++.
The standard doesn't specify that all "reads" are due to lvalue-to-rvalue
conversions, but I think one can state that all lvalue-to-rvalue conversions
count as "reads".
In C++, x = y = 0; makes a lvalue-to-rvalue conversion of the expression (y
= 0), and thus, "reads" the y object. This read is not done to compute its
new value. This is UB.
In C, there's nothing y=0 is a rvalue, and there's nothing stating the value
is read after the assignment (so, a fetch is either "unspecified" or
forbidden).
n1124> An assignment expression has the value of the left operand after the
assignment, but is not an lvalue.
I was curious enough to test existing practice.
#include <stdio.h>
volatile int x,y;
int main(void) {
printf("hello");
x=y=0;
printf("hello");
}
(The printf statements are useful as delimiters around the relevant compiled
code).
GCC on GNU/Linux/i386 fetches y, in both C99 and C++98 modes.
TCC on GNU/Linux/i386 doesn't fetch y.
Consequently, existing behavior differs between C99 implementations. I think
that's bad. It may be due to the ambiguous/defective standard wording, or a
GCC bug, perhaps because GCC uses the same back-end for C and C++.