From: diamond@jit345.bad.jit.dec.com (Norman Diamond)
Subject: New controversy Re: on "use", and the lvalue-ness of string literals
Reply-To: diamond@jit.dec.com (Norman Diamond)
Organization: Digital Equipment Corporation Japan , Tokyo
Date: Fri, 6 Nov 1992 08:52:32 GMT

In article <1992Nov2.162310.10094@ichips.intel.com> bhoughto@sedona.intel.com (Blair P. Houghton) writes:
>I'm sure Norman will be able to comment

Yeah, now that your original article finally arrived here, I can figure out
what everyone's been talking about.

>(having apparently nothing else to do in The Land of the Rebooting Sun)...
s/Sun/Digital/
s/Rebooting/[adjective deleted; for reason see preceding substitution]/

>Standard's use of the verb "to use" in the context of value contexts.
>I'm trying to develop a good definition, and it's come down to a few
>expression forms.  The important thing to remember is that it's the
>value, not the identifier or the location, that is being "used."
>	if ( foo ) ...;		/* uses `foo' */
>	foo;			/* does not use `foo' */
>	x = foo;		/* uses `foo' */
>	foo = x;		/* does not use `foo' */

2.1.2.3, page 8 lines 31 to 32:  "Accessing a volatile object, modifying
an object, modifying a file, or calling a function that does any of those
operations are all side effects."  OK, should "to use" a value mean
"to access" the underlying object?  Nope; maybe for volatiles, but not
necessarily others.  "To modify" the object?  Even less likely.

2.1.2.3, page 8 line 36:  "In the abstract machine, all expressions are
evaluated as specified by the semantics."  OK, should "to use" a value
mean "to evaluate" the underlying expression?  Tough question.  Let's
go SEMANTICS hunting.  But first...

3.3, page 39 lines 2 to 4:  "An expression is a sequence of operators
and operands that specifies computation of a value, or that designates
an object or a function, or that generates side effects, or that performs
a combination thereof."  OK, if an lvalue designates an object, then it
meets this definition of expression (so far), and we can't guess if it
also specifies computation of a value or not.

3.3.1, page 40 lines 9 to 10 (SEMANTICS):  "An identifier is a primary
expression, provided it has been declared as designating an object (in
which case it is an lvalue) or a function (in which case it is a function
designator)."  Hmm.  Does this mean that "foo;" does not get evaluated
at all?  In fact I think so, because in "foo = x;" foo is a primary
expression which does not get evaluated at all.

OK, I think I would guess that "to use" a value probably means
"to evaluate" the underlying expression.

So I would have to say:
	if ( foo ) ...;		/* uses `foo', though maybe invisibly[*] */
	foo;			/* does not use `foo' */
	x = foo;		/* uses `foo', though maybe invisibly[*] */
	foo = x;		/* does not use `foo' */
[* Unless foo is volatile, the access might be optimized out.]

In other words, I agree with your analysis.

But notice another unasked question that is answered by our analysis:
	foo;			/* DOES NOT ACCESS `foo' EVEN IF VOLATILE */
Now this one will probably be controversial.
****************************************************************************

>I'd say it was merely a matter of whether a side-effect depends on the value,
>but `if ( foo ) /* empty */;' does not have any side effects, but definitely
>does use the value of `foo'.  (Remember, "issues of optimization are irrel-
>evant," so the null statement WILL be "executed" in the "abstract machine.")

Furthermore 3.6.4, page 78 lines 8 to 9 (SEMANTICS) demand the value of the
controlling expression (though the access might be optimized out).

In article <18106@ksr.com> jfw@ksr.com (John F. Woods) writes:
<the expression statement ["foo;"] accesses the object named by the
<identifier "foo" and then discards the value of that object.

(Though the access might be optimized out.)  In the abstract machine, there
seems to be a funny kind of access, that doesn't compute a value and doesn't
modify a value.  "foo" does not get evaluated here.

<One would think that if "foo" were declared as "volatile", the object
<designated by "foo" here *must* be accessed in a running program.

I agree.  But what kind of access?  Neither fetch nor store but...

<3.5.3:  "What constitutes an access to an object that has volatile-
<qualified type is implementation-defined."

Yup.

<Perhaps, then, an implementation has the license to define that
<	foo;
<does not access the object referred to by foo, and/or that
<	foo = x;
<does, though in the first case I *think* that's stretching the license too far.

Close.  The implementation can define that the funny kind of access is a
no-op, and it's very unclear if that's stretching a license.  After all,
there was no evaluation.  In the second case, a modify access is pretty
well required (whatever the implementation defines for modify access).

<Remember that a strictly conforming program cannot use "volatile"; it is not
<a guarantee of portability, it is a "portable" way to beg for mercy :-).

I don't think so.  A strictly conforming program can use "volatile" on some
objects, such as auto variables (important after a longjmp() or maybe signal
handling) or other stuff that is in the program's name space.
--
Norman Diamond       diamond@jit081.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
"It's been a lovely recession."