This is the mail archive of the gcc-patches@gcc.gnu.org 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 astrees



On Thu, 13 Dec 2001, Linus Torvalds wrote:
>
> I'm not ignoring Jasons arguments. I'm refuting them with logical means,
> and claiming that the arguments are _bogus_.

Let my try a different approach.

Instead of trying to argue _against_ Jason's arguments, let me try to
argue _for_ the end result that I obviously think is the only logically
tenable one, but using Jasons vocabulary for the C++ case, ok?

 - "p = 0" is an expression, with a value.

	Proof: C and C++ standards.

 - "p = 0" is _also_ an lvalue in C++.

	Proof: C++ standard. 'nuff said.

	Existing gcc practice: "(p = 0) = 1" does in fact compile, and
	gives the expected results.

 - A lvalue as part of an expression (ie _not_ as the left side of an
   argument) is always converted to a rvalue, whether that rvalue is
   actually used or not.

	Proof: Neither C nor C++ really even _have_ a notion of whether
	a value is "used" or not. Expressions simply have values and
	statements do not. End of story.

	See also existing gcc practice, see the example of code generated
	for just a plain "p" when "p" is volatile. This is not meant as a
	"proof", but it _is_ clearly an indication that other parts of gcc
	(and most programmers) certainly think that the lvalue->rvalue
	conversion always happens, whether the rvalue is used or not.

 - Nobody expects the statement "p = 0;" to _read_ from "p".

	Proof: wild hand-waving, "ask anybody".

	Existing gcc practice: most definitely.

Do we agree on these four points?

I will consider the four points above to be a-priori _facts_, so
disagreement on the points above would certainly be a crucial point of
contention.  Please speak up.

But I also think that they are "clearly correct", and they are certainly
supported by existing gcc practice.

Now, let's look at what those two facts lead to, when combined.

 - the statement "p = 0;" contains the _expression_ "p = 0", which is not
   assigned to. Ergo, we have a lvalue expression that has a rvalue.

 - lvalues are _always_ converted to rvalues:

   Clearly, in the case of an assignment, that "conversion" cannot be a
   simple dereference, since that would violate rule #4 above. But we're
   in luck - the C++ standard actually tells us that the value of the
   assignment expression (the "rvalue") is the value we assigned. So we
   actually do _have_ a valid lvalue->rvalue conversion that is supported
   by the standard, and has nothing to do with dereferencing the lvalue.

This is my argument. I will claim that it is (a) consistent with the C/C++
language standards and (b) internally consistent and logical, without
resorting to any ill-defined "only when used" rules..

Now, Jason's argument goes:

 - Rule #3 does not exist, and we only do the lvalue->rvalue conversion
   "when needed".

	Proof: none.

	Existing gcc practice argues _against_ this interpretation of
	Jason. See simple "p".

 - lvalue -> rvalue conversion is always a dereference.

	Proof: "a variable is a lvalue, and the rvalue of a variable is
	the dereferencing of that variable. Thus the rvalue of a
	assignment (which is also a lvalue) is gotten through
	dereferencing the variable that is the assignment"

	Counter-proof: "Linus is a human, and Linus has blue eyes. Thus
	Jason (who is also human) also has blue eyes".

This is Jasons argument. With Jasons argument, a simple "p = 0" does _not_
dereference (because the rvalue is not used), but "q = p = 0" _does_
dereference "p" (because the value _is_ used, and a rvalue->lvalue
conversion is always a dereference).

According to Jason, "q = p = 0" becomes

	p = 0;
	q = p;

While _I_ think that "q = p = 0" becomes

	p = 0;
	q = (typeof p) 0;

(the "typeof" comes from the fact that the assigned value is converted to
the type of the assignee by the assignment as per normal C/C++ rules).

		Linus


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