This is the mail archive of the
mailing list for the GCC project.
Re: Volatile MEMs in statement expressions and functions inlined as trees
Alexandre Oliva wrote:
> On Dec 6, 2001, Jason Merrill <email@example.com> wrote:
> > However, the C++ standard says
> > The result of the assignment operation is the value stored in the left
> > operand after the assignment has taken place; the result is an lvalue.
> > in C++, *q should be read
> > after the store
I believe it to be implementation defined. Working from the C99 std
I have (I think C89 is the same in this respect, and Jason has already
pointed out that in C++ it's an lvalue so moot).
22.214.171.124 'Program Execution' talks about the abstract machine, side effects
and sequence points.
'The least requirement on a conforming implementation are:
-- At sequence points, volatile objects are stable in the sense
that previous accesses are complete and subsequent accesses have
not yet occurred.
There does not appear any mentioning that multiple accesses to a volatile
object between sequence points may or may not be folded. Ah - found
some more. 6.7.3 'type qualifiers' says
'An object that has volatile-qualified type may be modified
in ways unknow to the implementation or have other unknown
sideeffects. Therefore any expression referring to such
an object shall be evaluated strictly according to the rules
of the abstract machine as described in 126.96.36.199. Furthermore,
at every sequence point the value last stored in the object
shall agree with that prescribed by the abstract machine, execpt
as modified by the unknown factors mentioned previously.114)
_What constitutes an access to an object that has volatile-
qualified type is implementation defined._ [my emphasis]
footnote 114 says you can use these things to access memory mapped
io and the compiler can't 'optimize out' or reorder except as
permitted by the rules for evaluating expressions.
I remember this raising its head a couple of years ago, and I recall the
consensus was that even though
volatile int *p = whereever
int s = *p + *p;
could be optimized to
volatile int *p = whereever
int tmp = *p;
int s = tmp + tmp;
doing so would surprise.
Now to Linus's case of
*p = somevalue;
The language of 6.5.16 'Assignment operators' is unclear
'An assignment expression has the value of the left
operand after the assignment, but is not an lvalue'
But from the program execution clause, it appears a valid
tmp = somevalue;
store tmp into *p;
and this is what I think most programmers would expect. NOT doing this
will make it impossible to program memory mapped devices which have
different semantics on read & write (evil though they are).
We are already inconsistent wrt volatiles in C++, so that
has the 'expected' behaviour, rather than the standard specified one.
I think we should do the sensible thing here too, and the std allows
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
firstname.lastname@example.org : http://www.cs.bris.ac.uk/~nathan/ : email@example.com