Henry Spencer on C's
Henry Spencer sent me a reply to my previous entry
volatile that corrects some of my (mis)information, and I am
putting it here with his permission:
I fear you've miscalled this one. ANSI C pre-dates aggressive memory controllers in consumer CPUs, but it had extensive participation by people in the supercomputer world as well, and such things were common there long ago.
The key issue you've missed is that ANSI C doesn't really acknowledge the existence of a "compiler". It's phrased almost completely in terms of an "implementation", which takes in source code and spits out execution results. It is the implementation's responsibility to ensure that accesses to `volatile' variables happen in the order specified. If the implementation consists of a compiler plus a CPU, it is the compiler's job to make the CPU do the right thing, however difficult that may be.
There is some leeway here, because some aspects of the precise definition of the "right thing" are up to the implementation... but ANSI C does require that they be documented.
Compiler implementers -- except on supercomputers -- are notoriously casual about these issues, but it is technically their responsibility to establish exact rules and then force the hardware to live up to them.
It is unfortunately true that memory barriers etc. are a complicated subject, and `volatile' is too simplistic (and has too many different uses) to capture all of what people want done.
I suspect that the gcc people would counter-argue from two possible positions:
- because threading and memory semantics are not defined in ANSI C,
no strictly conforming ANSI C program can have shared state issues
that require memory barriers, and so the compiler is not required to
implement them for
volatileaccesses; the compiler-level actions are good enough.
- almost all code (mis)uses
volatilein ways that do not require memory barriers and which would slow down significantly if memory barriers were introduced. Thus, regardless of the letter of ANSI C,
volatileaccesses will not introduce memory barriers.
Especially if the first is correct, this reduces gcc's sins to at most failing to document what volatile does and doesn't do (and I'm not convinced that they're even failing at that; they do have a small section about it in the info docs, which might be good enough in that it doesn't say that they do do memory barriers et al).