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 inlinedastrees


(please see annotations below)

on 1/7/02 1:55 PM, Jason Merrill wrote:
>>>>>> "Paul" == Paul Schlie <schlie@mediaone.net> writes:
> 
>> It seems to be agreed that the value of assignment expression as an:
> 
>> - lvalue, is equivalent to the lvalue of that assignment expression.
>> - rvalue, is equivalent to the rvalue of that assignment expression.
> 
>> It further seems agreed that the terms "lvalue", and "rvalue" are semantic
>> terms, where: (please excuse my terminology, but intent should be clear)
> 
>> - lvalue, refers to the "state-location" of a referenced "symbol" or
>>   "expression-value" (only symbols and expressions explicitly yielding
>>   reference-values are valid lvalues-expressions, no dereferencing of the
>>   resulting lvalue is implied or required).
> 
> Yes.
> 
>> - rvalue, refers to the "state-value" of the referenced symbol or
>>   "expression-value" (all valid expressions have valid state-values, and
>>   do imply (and require if volatile) dereferencing
> 
> Yes.
> 
>> The controversy appears to be related to if and/or when it is necessary, or
>> even appropriate to require the re-evaluation an assignment expression's
>> lvalue to derive it's rvalue when required for subsequent evaluation,
> 
> Yes.
> 
>> and if the semantics of an statement evaluation (which semantically
>> yields no value in C, unlike other languages such as scheme), implies the
>> the semantics of an <lvalue> or <rvalue> be applied to the enclosed root
>> expression.
> 
> Well, sort of.
> 
>> It is unreasonable to believe that the expression:
> 
>> X = Y; :: X = Y, X;
> 
>> Where if X were declared as volatile, would require X be sequentially
>> write-accessed, and then read-accessed, which seems clearly wrong; as it
>> would then be impossible to specify write-access to the exclusion of a
>> subsequent read-access of a volatile variable.
> 
> Agreed.  There is no second read in this statement.
> 
>> Therefore one of the following must be true to for volatile X:
> 
>> X = Y; :: X = Y;
> 
>> - the root statement-expression is treated as an <lvalue> evaluation, which
>>   does not imply or require the dereferencing of the resulting lvalue,
>>   therefore no terminal dereference of X.
> 
> More or less.  More precisely, it's treated as a void evaluation, which
> doesn't require anything.
> 
>> - the root statement-expression is treated as an <rvalue> evaluation, where
>>   the resulting <rvalue> is thrown away, and assignment sub-expression's
>>   return "the value written", in the form of a temporary (or optionally by
>>   re-evaluating the lvalue target if non-volatile).
> 
> No.
> 
>> Therefore under no circumstances does:
> 
>> (X = Y) :: (X = Y, X)
> 
>> Except if X is non-volatile, and therefore can be re-de-referenced as an
>> optimization to an otherwise required intermediate temporary, therefore not
>> semantically equivalent.
> 
> No, that equivalence holds in all cases in C++.  But this only matters if
> the resulting value is used in a further expression.
> 
>> In all circumstances:
> 
>> (X = Y) :: (temp = Y, X = temp)
> 
>> Regardless if X or Y are volatile, I have found no reference in the C
>> standard to support alternative fully constant conclusions.
> 
> Yes, but this is vacuous.
> It is further equivalent to (temp = Y, X = temp, X).

Agreed when evaluated in the context of an <lvalue>.

But not as an <rvalue>, as it would require X to be subsequently
re-evaluated, which was agreed as being inappropriate; therefore more
specifically, an assignment expression has different semantics depending on
if it is evaluated as an lvalue, or rvalue (just as most expressions do).

<lvalue> (X = Y) :: (temp = Y, X = temp, X)
<rvalue> (X = Y) :: (temp = Y, X = temp, temp)

Which should account for all concerns, and be fully consistent.

> I'm only talking about C++ here.  In C, the result of an assignment is an
> rvalue, so
> 
> (X = Y) :: (temp = Y, X = temp, temp)

Agreed as above, when evaluated in the context of an <rvalue>.

> The only question as to whether or not evaluation of an lvalue as a
> statement should cause a read from a volatile variable was in reference to
> simple statements like
> 
>  x;  or
>  *p;

Ultimately would suspect to be uniformly consistent it would need to be
determined if an expression is evaluated as being in the context of an
lvalue or rvalue; where:

<lvalue> implies no dereference of X, or *p, therefore no volatile access.
<rvalue> implies a dereference of X, and *p, therefore a volatile access.

Personally I prefer <lvalue>, but also somewhat indifferent; assuming it
is accepted that assignment statements have different lvalue and rvalue
semantics, although <rvalue> semantics would largely preserve present
volatile behavior.

> 
> for which there is a GCC extension to perform the read even though it is
> not required by the language.  There has been some discussion about whether
> or not this is appropriate; I have no strong feeling on the subject.  I
> would be happy to accept a patch to change this behaviour, so long as it
> also adds a warning.
> 
> Jason


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