This is the mail archive of the
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: Alexandre Oliva <aoliva at redhat dot com>
- Cc: Richard Henderson <rth at redhat dot com>, <gdr at codesourcery dot com>, <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 14 Dec 2001 11:39:36 -0800 (PST)
- Subject: Re: Volatile MEMs in statement expressions and functions inlined astrees
On 14 Dec 2001, Alexandre Oliva wrote:
> > See? We end up reloading 'a' - simply because on the left side of the
> > assignment we have to use the lvalue.
> Interesting. That's a very reasonable and consistent approach. But
There's always a "but.." ;)
> ``The behavior of an expression of the form E1 op= E2 is equivalent
> to E1=E1 op E2 except that E1 is evaluated only once.'' [expr.ass]/7
> seems to imply that:
> (a += b) += c;
> should be equivalent to
> a = (a += b) + c;
The way I parse it, E1 is "(a += b)" and E2 is "c", with "op" being "+".
So the correct expansion of "E1 op= E2" to "E1 = E1 op E2" is in fact
(a += b) = (a += b) + c;
together with the "evaluate only once" clause. Agreed? That is _not_
really equivalent to your expansion.
But to be quite honest, I have no idea _what_ it is equivalent to, as that
expression just makes me go "Huh!?" ;)
My argument hinges on the fact that I think evaluating "(a += b)" returns
two different things, both an rvalue _and_ an lvalue, and which of them is
"E1"? E1 should be the _same_ on both sides, and on the left side it has
to be a lvalue, so you can argue that the right side should also use the
lvalue, and that would make "(a += b) = (a += b) + c;" (with the "only
once") really become
a += b;
a = a + c; // reload 'a'
while if you say that E1 is the lvalue on the left side, and a different
entity (the rvalue) on the right side, then you do indeed get
a += b; // "tmp" = rvalue, ie the value of "a+b".
a = tmp + c; // no reload.
So I think it depends on what you think E1 is. Does it mean
E1 = (lvalue) (a+=b)
E1 = E1 + c
or does it mean
E1.left = (lvalue) (a+=b)
E1.right = (rvalue) (a+=b)
E1.left = E1.right + c;
I vote for the first one, but I'll admit that that is mainly because it
gets the behaviour I want ;)