Volatile MEMs in statement expressions and functions inlined as trees

Linus Torvalds torvalds@transmeta.com
Thu Dec 13 00:10:00 GMT 2001


In article <fln10n370l.fsf@riz.cmla.ens-cachan.fr> you write:
>
>Absolutely not.  Please re-read what Jason said -- the result of the
>assignment is an *lvalue*.  Thus
>
>	p = 0;
>
>is equivalent to
>
>	(p = 0, &p);

You and Jason must be on drugs.

The above is obvious crapola, as the above has the value of "&p", _not_
a value of 0 (or that value re-loaded from p).

So clearly "p = 0" is _not_ equivalent to "(p = 0, &p)", and claiming it
is equivalent is just stupid and misguided.

I stand by my argument.  Whether you _use_ the value of an assignment or
not MUST NOT CHANGE THE SEMANTICS OF THE ASSIGNMENT.  The fact that a
C++ compiler thinks that an assignment is also an lvalue does not change
things one _iota_.  Jasons arguments that it has any relevance are
illogical, and make no sense, simply because the equivalence that he
(and you) claim exists obviously does NOT exist. 

Note that the notion of "lvalue" does _not_ have any meaning for whether
a value is loaded or not.

Let's take a really simple example:

	volatile int p;
	p;

It doesn't get much simpler than that.  Here, the expression is "p", and
that expression is an lvalue, and it is supposed to have the value that
you load from the memory location pointed to by "&p". And I would claim
that people would expect that memory location to be dereferenced, even
though yes, the expression is _also_ an lvalue.

Yet Jason somehow seems to claim that expressions that are lvalues are
magical and different.  Baloney, says I.  The notion of "lvalue" means
_nothing_ but the fact that it can instead of being dereferences also be
assigned. 

So when we write "p = 0", we _still_ have an expression that is an
lvalue.  That fact (as shown above), has _nothing_ to do with whether
"p" gets dereferenced or not, and Jason claiming that it is relevant has
shown no support for his argument.  His only support (the fake
equivalence) has no basis in reality. 

The fact that "p = 0" is an lvalue _only_ means that it is also legal to
write "(p = 0) = 1", and expect "p" to be assigned _twice_. First with
the value 0, then with the value 1. Do you disagree?

I claim that "q = p = 0" is an expression that parses the other way
around, ie "q = (p = 0)", where the inner expression "p = 0" is indeed
an lvalue, but that is irrelevant. Whether it is an lvalue or not, it is
always supposed to return the value that got assigned.

And it is supposed to return that value _whether_ the value is used or
not.  The expression "p = 0" has not changed just because the return
value is used.  And as "p" is volatile, I will claim that it is WRONG to
access "p" any more or any less regardless of whether the value of the
assignment is used or not - the whole _point_ of volatiles is that
accesses to them are "stable" (never mind the fact that the definition
of "stable" is not very good). 

So if you do not dereference "p" when you do "p = 0", then I claim that
you should not dereference "p" when you do "q = p = 0". All the
expressions involving "p" are _exactly_ the same in the two expressions.

And _everybody_ agrees with the fact that "p = 0" should _not_ read the
value of "p".  Thus "q = p = 0" should _also_ not read the value of "p",
as _nothing_ has changed wrt "p".  We added an assignment to "q", not a
dereference of "p". 

		Linus



More information about the Gcc-patches mailing list