[comp.std.c] Interpretation of volatile - two questions

rfg@paris.ics.uci.edu (Ronald Guilmette) (03/19/90)

Assume you have the following structure:

	struct s {
		char		c1;
		volatile char	c2;
	};

Now assume that you also have:

	struct s *memory_mapped_device_p = (struct s *) 0xffffff80;

Now if you also have:

	void foo ()
	{
		char c;

		c = memory_mapped_device_p->c1;
	}

does the standard (a) permit, (b) require, or (c) prohibit the assignment
statement shown to access the c2 field of the "struct s" pointed to by
memory_mapped_device_p?

This could be important in cases where you have certain locations which
(when read) produce side-effects.


// Ron Guilmette (rfg@ics.uci.edu)
// C++ Entomologist
// Motto:  If it sticks, force it.  If it breaks, it needed replacing anyway.

henry@utzoo.uucp (Henry Spencer) (03/20/90)

In article <2604A628.8521@paris.ics.uci.edu> rfg@paris.ics.uci.edu (Ronald Guilmette) writes:
>	struct s {
>		char		c1;
>		volatile char	c2;
>	};
>...
>		c = memory_mapped_device_p->c1;
>...
>does the standard (a) permit, (b) require, or (c) prohibit the assignment
>statement shown to access the c2 field of the "struct s" pointed to by
>memory_mapped_device_p?

The standard, by and large, is silent about the *details* of how volatile
works.  Necessarily so; it's very machine-specific.  Suppose your machine's
bus only does word accesses, and it *cannot* access c1 without also
touching c2?  In general, you have to know the machine and the compiler
to know the exact semantics in such situations; the method of specifying
volatility is machine-independent, but the results are not.
-- 
MSDOS, abbrev:  Maybe SomeDay |     Henry Spencer at U of Toronto Zoology
an Operating System.          | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

gwyn@smoke.BRL.MIL (Doug Gwyn) (03/20/90)

In article <2604A628.8521@paris.ics.uci.edu> rfg@paris.ics.uci.edu (Ronald Guilmette) writes:
>does the standard (a) permit, (b) require, or (c) prohibit the assignment
>statement shown to access the c2 field of the "struct s" pointed to by
>memory_mapped_device_p?

It requires that the implementation document its rules for access to
volatile objects, which presumably should include cases of access to
such an object as a side effect of accessing a non-volatile one, as
in your example.  Obviously choice (b) would have been silly and
choice (c) would be an impossible constraint on some architectures.

iiitsh@cybaswan.UUCP (Steve Hosgood) (03/21/90)

In article <1990Mar19.165931.22758@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>In article <2604A628.8521@paris.ics.uci.edu> rfg@paris.ics.uci.edu (Ronald Guilmette) writes:
>>	struct s {
>>		char		c1;
>>		volatile char	c2;
>>	};
>>...
>>		c = memory_mapped_device_p->c1;
>>...
>>does the standard (a) permit, (b) require, or (c) prohibit the assignment
>>statement shown to access the c2 field of the "struct s" pointed to by
>>memory_mapped_device_p?
>
>The standard, by and large, is silent about the *details* of how volatile
>works.  Necessarily so; it's very machine-specific.  Suppose your machine's
>bus only does word accesses, and it *cannot* access c1 without also
>touching c2?

In this latter case, surely the 'expected' compiler action should be to
print an error message to the tune of 'cannot generate code on this machine'.
After all, it can't be right for a compiler to generate code that does
an invisible access to a volatile - even if it can't help it.

Steve

daveg@near.cs.caltech.edu (Dave Gillespie) (03/22/90)

> In article <2604A628.8521@paris.ics.uci.edu> rfg@paris.ics.uci.edu (Ronald Guilmette) writes:
>	struct s {
>		char		c1;
>		volatile char	c2;
>	};
>...
>		c = memory_mapped_device_p->c1;
>...
>does the standard (a) permit, (b) require, or (c) prohibit the assignment
>statement shown to access the c2 field of the "struct s" pointed to by
>memory_mapped_device_p?

Henry Spencer and Doug Gwyn point out that on a word-addressed machine
it may not be possible to read c1 without touching c2 as well.  But it
seems to me that compilers have the flexibility to pad out structures
in order to avoid this---a compiler on such a machine could surround a
volatile object with enough padding to keep it isolated.

Even if the standard does not specify (c), it seems to me that it
reasonably *could*.

								-- Dave
--
Dave Gillespie
  256-80 Caltech Pasadena CA USA 91125
  daveg@csvax.caltech.edu, ...!cit-vax!daveg

ray@philmtl.philips.ca (Ray Dunn) (03/22/90)

In referenced article, daveg@near.cs.caltech.edu (Dave Gillespie) writes:
>Henry Spencer and Doug Gwyn point out that on a word-addressed machine
>it may not be possible to read c1 without touching c2 as well.  But it
>seems to me that compilers have the flexibility to pad out structures
>in order to avoid this---a compiler on such a machine could surround a
>volatile object with enough padding to keep it isolated.
>
>Even if the standard does not specify (c), it seems to me that it
>reasonably *could*.

Only having K&R II to work with I may be on the wrong track, but I don't see
the relevance here to volatile.

Surely volatile only ensures that no references to the qualified variables
are optimized *out*, not that no hidden references are created.  Is there
*any* mention of the latter?

I don't believe it's the job of the compiler to give such assurances other
than that no reference will be optimized out.

The programmers' requirements in these cases are so machine dependant, and
*application* dependant, that the compiler could never be expected to modify
it's behaviour in the required best way.  A cross compiler for a particular
micro-processor has *no* knowledge about the architecture (memory and I/O
for example) that the compiled code will be running in.  These
considerations must always be left up to the programmer to handle.
-- 
Ray Dunn.                    | UUCP: ray@philmtl.philips.ca
Philips Electronics Ltd.     |       ..!{uunet|philapd|philabs}!philmtl!ray
600 Dr Frederik Philips Blvd | TEL : (514) 744-8200  Ext : 2347 (Phonemail)
St Laurent. Quebec.  H4M 2S9 | FAX : (514) 744-6455  TLX : 05-824090

gwyn@smoke.BRL.MIL (Doug Gwyn) (03/23/90)

In article <DAVEG.90Mar21203033@near.cs.caltech.edu> daveg@near.cs.caltech.edu (Dave Gillespie) writes:
>... a compiler on such a machine could surround a
>volatile object with enough padding to keep it isolated.

There are two problems with this.  The minor one is that it wasn't the
intention of X3J11 (as I understand it) for type qualifiers to affect
representations, which is what an impact on padding would amount to.
The more important one is that examples like the one we were using are
typical of access to device registers, for which spurious padding
would simply mean inability to access some of the register contents.
I've encountered examples of Unibus devices and PDP-11 CPU memory
access combinations where one had to be extraordinarily careful, due
to such things as a WRITE cycle having a different effect from a
READ-MODIFY-WRITE.  There is a limit to how much of this sort of thing
can reasonably be reflected in C language rules, which is one of the
reasons that the meaning of volatile access is implementation defined.