[comp.lang.c] does \"volatile\" cover this?

rgenter@j.bbn.com (Rick Genter) (12/25/86)

I was perusing some code today and noticed a situation where even declaring
a variable (volatile) may not be sufficient, depending on how X3J11 is
interpreted.

Specifically, assume I have the following code fragment:

	jmp_buf		state;
	volatile RESULT *r;		/* I want a volatile pointer to a
					   RESULT */

	RESULT	*ResultComp ();
	
	[...]
	
	if ( setjmp (state) == 0 ) {	/* no error condition (yet) */
		r = (RESULT *) NULL;	/* flag in case ResultComp fails 
					   (indication given by 
					   longjmp (state, 1)) */
		r = ResultComp ();
		[ other computations which may also cause a 
		  longjmp (state, 1)) ]
	}
	
	else	{
		if ( r == (RESULT *) NULL ) {
			/* ResultComp () failed */
		}
	}

According to the April 30, 1985 draft of the C Information Bulletin released
by X3J11 (section C.2.2.4 "*const* and *volatile*"):

	"An object declared with the *volatile* type specifier may be
	 modified in ways unknown to the implementation or have other
	 unknown side effects.  Therefore any expression referring to
	 such an object must be evaluated strictly according to the
	 sequence rules of the abstract machine.  Furthermore, at every
	 sequence point the value of the object in storage must agree
	 with that prescribed by the abstract machine, except as modified
	 by the unknown factors mentioned previously."

Unfortunately, every place that I can find that discusses sequence points
refers explicitly to points within expressions.  Side effects across multiple
statement boundaries are not discussed, from what I can find.  (Note: section
B.1.2.3 "Program execution" claims:

	"The semantic descriptions in this document describe the behavior
	 of an abstract machine in which issues of optimization are irrelevant.
	 The actual execution of a program is not required to mimic every
	 operation of the abstract machine.
	
				[ ... ]
	
	 In the abstract machine, all expressions are evaluated as specified
	 by the semantics.  An actual implementation need not evaluate part
	 of an expression if it can deduce that its value is not used and
	 that no side effects are produced (including any caused by calling
	 a function or accessing a volatile object).
	
	 When the processing of the abstract machine is interrupted by receipt
	 of a signal, only the data values as of the previous sequence point
	 may be relied on.  Data that may be modified between the previous
	 sequence point and the next sequence point are unreliable.
	
				[ ... ]
	
	 The least requirements of a conforming environment are:
	
				[ ... ]
	
		* At sequence points, volatile objects are stable with respect
		  to previous evaluations being complete and subsequent
		  evaluations not yet having occurred."

In the Forward References: note at the end of the section, "sequence points"
are indicated in section C.3, but I couldn't find any text discussing sequence
points there, either in the introduction or under C.3.16, "Assignment
operators".)

Now that I've gotten all the preliminary information out of the way, here's the
question.  Does the above wording preclude optimizing out the "r = NULL;"
statement in the above example?  I can't convince myself that a conforming
implementation couldn't still delete the statement, even with r declared as
(volatile RESULT *).

Obviously if the most recent draft ($65 :-() has significantly different wording
then my question may be moot.
				- Rick
--------
Rick Genter 				BBN Laboratories Inc.
(617) 497-3848				10 Moulton St.  6/512
rgenter@bbn.COM  (Internet new)		Cambridge, MA   02238
rgenter@bbnj.ARPA (Internet old)	seismo!bbncca!rgenter (UUCP)

jsdy@hadron.UUCP (Joseph S. D. Yao) (01/03/87)

From an older X3J11 (my new copy is "in the mail"):

6. STATEMENTS
... Completion of the evaluation of the expression [ in if (expr) ... ]
is a sequence point.
6.2 Expression and null statements
... The terminating semicolon is a sequence point.

Hope this makes you happy.  Your situation (two sequential
assignments to the same location) is exactly one of the
situations for which "volatile" was invented, to prevent
"intelligent" optimisers from doing clever things to it.
-- 

	Joe Yao		hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}
			jsdy@hadron.COM (not yet domainised)

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/05/87)

In article <2028@brl-adm.ARPA> rgenter@j.bbn.com (Rick Genter) writes:
>	volatile RESULT *r;		/* I want a volatile pointer to a
>					   RESULT */

Then you should specify:
	RESULT *volatile r;
The way you had it, it was a pointer to a volatile RESULT.

>Unfortunately, every place that I can find that discusses sequence points
>refers explicitly to points within expressions.  Side effects across multiple
>statement boundaries are not discussed, from what I can find.

The end of an expression that is not part of another expression is
a sequence point (section 3.6 in the current draft).

>Now that I've gotten all the preliminary information out of the way, here's the
>question.  Does the above wording preclude optimizing out the "r = NULL;"

Yes, since there is a sequence point after the ;.

>Obviously if the most recent draft ($65 :-() has significantly different wording
>then my question may be moot.

The current draft's wording about sequence points is quite
different, although the idea is basically the same.