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.