Volatile MEMs in statement expressions and functions inlined as trees

Fergus Henderson fjh@cs.mu.OZ.AU
Thu Dec 27 11:33:00 GMT 2001


On 25-Dec-2001, Linus Torvalds <torvalds@transmeta.com> wrote:
> Also, you're ignoring the difference between "undefined" and
> "implementation defined".

No, I'm not.  I just don't happen to have the definitions of
implementation-defined stuff for lcc.  For lcc, maybe the definitions of
implementation-defined stuff are in "A Retargetable C Compiler: Design
and Implementation" (Addison-Wesley, 1995, ISBN 0-8053-1670-1).  Or maybe
they're not.  Maybe lcc doesn't conform to the documentation requirements.

In practice the documentation requirements seem to be often ignored.
For example GNU C 2.95 does not include any such documentation.
(Has this improved in 3.x?)

But for the purposes of this discussion, it doesn't really matter much
whether lcc does conform to those requirements; it's more important to
know whether it _could_ conform, given appropriate documentation.

> For example: I claim that it's ok to play towers-of-hanoy on "access" to a
> volatile object, but because behaviour is _implementation_defined_ rather
> than undefined, the compiler should (a) _document_ the choice to do so,
> and (b) do so consistently (or document when it doesn't).

I disagree.  Here you are talking about the *effect* of accessing
a volatile object, not what *constitutes* accessing a volatile object.

In particular, if the following program, when compiled and run in an ordinary
manner, plays Towers of Hanoi, then IMHO the compiler does not conform.

	int main() {
		volatile int x = 0;
		return x;
	}

If the implementation were to say that "playing the towers of Hanoi" is what
constitute access to a volatile object, then this would only make a difference
if the program happened to be a program to play the towers of Hanoi!

I think the reason why the issue of what constitutes access to a volatile
object is implementation-defined is because implementations differ about
issues such as whether accessing (in the ordinary sense) a bitfield also
constitutes an access to an adjacent volatile bitfield.  That's a completely
different thing from asking the implementation to define what effect
accessing a volatile value would have; in general the implementation
won't know, so how could it be expected to define that?

> In contrast, you seem to think that implementation-defined means that the
> compiler can choose to ignore the rules of C, and not just choose "what
> constitues an access", but lcc _also_ seems to choose when to do the
> access and when _not_ to do the access.

I don't think a compiler can choose to ignore the rules of C.  However,
I do think that "access to a volatile object" is not necessarily the same
as ordinary "access" (in the sense of 3.1[#1]) to a "volatile object".
That's a matter of interpreting the language in the standard.
It seems to me that "access to a volatile object" has to be a separate
term, otherwise the statement that "what constititutes access to a volatile
object is implementation-defined" would be nonsensical, since the other
parts of the standard would already have defined it.

(I'm using "volatile object" here as an abbreviation for
"object with a volatile-qualified type".)



P.S.
Here's some extracts from implementation documentation for

     * What constitutes an access to an object that has
       volatile-qualified type

Microsoft:
 |    Any reference to a volatile-qualified type is an access.

Sun:
 |    Each reference to the name of an object constitutes one access to the
 |    object.

SGI:
 |     Objects of volatile-qualified type are accessed only as specified
 |     by the abstract semantics, and as would be expected on a RISC
 |     architecture, no complex instructions exist (for example,
 |     read-modify-write). Volatile objects appearing on the left side of
 |     an assignment expression are accessed once for the write. If the
 |     assignment is not simple, an additional read access is performed.
 |     Volatile objects appearing in other contexts are accessed once per
 |     instance. Incrementation and decrementation require both a read
 |     and a write access.
 |     Volatile objects that are memory-mapped are accessed only as
 |     specified. If such an object is of size char, for example,
 |     adjacent bytes are not accessed. If the object is a bitfield, a
 |     read may access the entire storage unit containing the field. A
 |     write of an unaligned field necessitates a read and write of the
 |     storage unit that contains it.

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.



More information about the Gcc-patches mailing list