This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Volatile MEMs in statement expressions and functions inlined astrees
- From: Linus Torvalds <torvalds at transmeta dot com>
- To: Fergus Henderson <fjh at cs dot mu dot oz dot au>
- Cc: <gcc-patches at gcc dot gnu dot org>, Nathan Sidwell <nathan at codesourcery dot com>
- Date: Mon, 17 Dec 2001 10:28:17 -0800 (PST)
- Subject: Re: Volatile MEMs in statement expressions and functions inlined astrees
On Tue, 18 Dec 2001, Fergus Henderson wrote:
> On 13-Dec-2001, Linus Torvalds <torvalds@transmeta.com> wrote:
> >
> > For an expression like
> >
> > extern volatile in p;
> > p;
> >
> > you would expect to see the assembly code to contain a dereference of "p",
> > would you not?
>
> No. I wouldn't know what to expect.
Well, how about reading the C++ standard on what "volatile" means?
As far as I can tell, there are only two places that actually talk about
the _meaning_ of volatile, as opposed to just mentioning it as a
cv-qualifier. The places I've found (please add your own list here) are:
1.9: Accessing an object designated by a volatile lvalue (3.10),
modifying an object, [ ... ] are all {\it side effects}, which are
changes in the state of the execution environment.
7.1.5.1: In general, the semantics of volatile are inteded to be the same
in C++ as they are in C.
Do you find any other place that talks about the _semantics_ of volatile?
Now, in C, the meaning of
volatile int p;
p;
is pretty clear: we _will_ load the value from "p", because the value of
the expression is the value of "p" and C does not have any of the lvalue
vs rvalue confusion that C++ has. That expression _is_ an rvalue, and as
such there is absolutely _no_ difference between the rvalue expression "p"
and the rvalue expression "p" in the expression statement:
int i;
volatile int p;
i = p;
Agreed? In both cases, "p" means the value of the volatile object, and in
both cases the expression "p" is _exactly_ the same.
(This is where C++ is different, much to my surprise - the "p" in "p;" is
an lvalue, and the "p" in "i = p;" is an rvalue. This distinction
definitely does _not_ exist in C).
It sounds like lcc and Sun cc have gotten confused about C semantics, and
I suspect that the _reason_ for the confusion is that they're trying to
compile C++ too, a language that is inherently confused about this.
Now, we've seen that 7.1.5.1 claims that C++ semantics for "volatile" are
"intended to be" the same as the C semantics, so there would be a
preference for them to be the same. But "intended to be" and "are" are
clearly two different things: the former depends on the intender being
fully aware of what else is going on.
In contrast, in clause 1.9 we don't have any confusion about "intentions",
but only straight statements about "access" and the fact that you cannot
optimize it away because it is an externally visible side effect. Agreed
so far?
However, as Nathan Sidwell pointed out, even gcc documentation points out
that nowhere does the C++ standard seem to say _when_ an access actually
happens, which is why gcc considers this an implementation defined issue
and sometimes does it and sometimes doesn't. In particular, gcc
documentation itself seems to agree with me that the "access" is _not_
directly associated with the standard l-r-conversion.
Now, gcc documentation is by no means the final word. It's incomplete, and
can often be wrong. Maybe it should be fixed. Who knows. The point being,
that I'm not the only one who claims that "l-r-conversion" is _not_ the
same thing as "access".
So, put the three together:
- C semantics are clear: the expression "p" is _identical_ in both of
the statements "p;" and "i = p;". It should thus behave the same way.
- C++ semantics are less clear, but gcc documentation implies that the
access is _allowed_ by the standard, and the standard clearly does say
that C++ semantics are _indended_ to be identical to C semantics.
So what do you say?
In short:
I claim, that nobody can deny that the statement "i = p;" _must_ access
"p", and that the access cannot be optimized away because "p" is volatile.
I further claim that the expression in "p;" is identical to the expression
in "i = p;" in the C language. Do you have _any_ arguments otherwise?
Speak up. If the two expressions are the same, then clearly the simpler
statement "p;" must _also_ access "p", and cannot be optimized away.
I further claim that the C++ standard says that C++ semantics for volatile
are intended to be the same as for C.
Draw your own conclusions.
Am I delusional, or can you see why I claim that it is perfectly
reasonable to expect the statement "p;" to read the value contained in
"p"?
Counter-arguments?
Linus