This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Volatile MEMs in statement expressions and functions inlined as trees

Alexandre Oliva wrote:
> On Dec  6, 2001, Jason Merrill <> 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). '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 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
translation is

	tmp = somevalue;
	store tmp into *p;
	return tmp;
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
us too.


Dr Nathan Sidwell   ::   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?' : :

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]