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 inlinedastrees
- From: Linus Torvalds <torvalds at transmeta dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: Alexandre Oliva <aoliva at redhat dot com>, <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 16 Dec 2001 11:51:38 -0800 (PST)
- Subject: Re: Volatile MEMs in statement expressions and functions inlinedastrees
On Sun, 16 Dec 2001, Jason Merrill wrote:
>
> > - "lvalue->rvalue conversion is NOT the same as 'access' when evaluating
> > the expression"
> > - "gcc is currently buggy because it _does_ do the access even though
> > the standard says no lvalue->rvalue conversion takes place".
>
> > I think you can choose one or the other, but not both.
>
> I think if you're a bit weaselly, you can choose both. Because the
> standard doesn't define what is or is not an "access", we are free to say
> that arbitrary uses are "accesses".
Hey, call me "Mr Weasel", but I have nothing against that.
> But the definition of the l-r conversion requires a read, regardless
> of whether you call it an "access".
But even Mr Weasel disagrees with this, for two reasons:
- the notion of "volatile" is only _defined_ as a property of "access":
1.9: Accessing an object designated by a volatile lvalye (3.10),
modifying an object, [ ... ] are all {\it side effects}, which are
changes in the state of the execution environment.
So "whether you call it in 'access'" actually _matters_, because that
word is used in the definition of what "volatile" actually means.
So if you don't call it an access, then it doesn't merit as having side
effects, and if it doesn't have side effects you might as well throw it
out.
(Side note: the previous sentence to this sentence, btw, quite clearly
implies that "access" just means "reads or writes", so I don't think
your weasel-words really work. You can't just call it a "read" and try
to weasel out that way, because 1.9 implies that a read _is_ a form of
access)
- the l-r conversion doesn't require a read. As mentioned earlier, the
l-r-conversion is not really even a run-time conversion, but entirely a
semantic conversion. It happens even in the absense of any code
generation at all.
Another way of saying this: the l-r-conversion only changes the
"meaning" of "a" from a lvalue to a rvalue, it doesn't necessarily
change the _code_generated_.
So I think you can validly consider the distinction between "lvalue"
and "rvalue" to be purely a syntactic distinction, not one that
necessarily has any impact on the code generated.
Yes, the "the value contained in the object indicated by the lvalue is
the rvalue result". But the standard is silent on whether the lvalue
itself might have a result - from a code generation standpoint, you
could say that "the value contained in the object indicated by the
lvalue is also the _l_value result", which in turn might allow another
weasel to generate the same code whether there is a rl-conversion or
not.
Hey, it was _you_ who started the weasel-words. Don't blame me for just
being even more weasely.
(Sub note: 7.1.5.1 actually says: "In general, the semantics of volatile
are inteded to be the same in C++ as they are in C", so you can actually
solve the problem by alternate means: your weasel-words basically means
that "access" itself is not defined, and thus the C++ notion of volatile
really is not defined in itself - but 7.1.5.1 says to follow C semantics
for how "volatile" behaves).
That said, I really think consistency is more important than the subtle
detail of _what_ the consistency is, so I don't think your suggestion is
bad:
> Personally, I'd prefer to drop the access for plain 'i;' because it is
> inconsistent, and replace it with a warning about an expression with no
> effect. But there's probably code that relies on it.
I don't disagree. And I actually doubt that there is any C++ code that
really relies on it - there are very few people indeed who use C++ for
low-level hardware accesses.
How about a _new_ warning (only for C++), and one that is enabled by
default:
test.cpp: 45: unused volatile lvalue has no effect
(and, as the message implies, only make that warning happen for volatile
lvalues, and only for C++ where the behaviour would be different).
I doubt you'll find any normal code that triggers it, and it should be
easy enough to add a C++ test for it in the gcc test-suite (ie the test is
just
volatile int i;
main() { i; return 0; }
and testing that the compiler warns about it.
Linus