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.