volatile isn't necessary, but it's there

dmr at alice.UUCP dmr at alice.UUCP
Wed Apr 6 15:40:36 AEST 1988


Since a good many messages have ardently defended the 'volatile'
type qualfier, it might be worth pointing out a few things.

Most important, the notion is not, so far as I know, under serious attack
in X3J11; there is every reason to believe it will be in ANSI C.
In my noalias diatribe I took a passing swipe at it (a position
I will defend below), but on the whole, I am willing to leave volatile
alone and concentrate on getting rid of noalias.

Volatile is of use only with optimizing compilers; those that don't
do some kind of data-flow analysis can ignore it.  More bluntly,
it is intended to be used in cases where your compiler will do something
other than what your program plainly asks it to do.  People seem to be
thinking of three categories of use.

1)  Accessing memory-mapped device registers

2)  Special cases involving automatic variables in a routine
    that calls setjmp

3)  Shared memory, and also interrupt routines.

The X3J11 documents (the dpANS itself and the Rationale) specifically
mention the first two, but carefully avoid talking about the third.

I have no real gripe about the first; I just think it is unnecessary.
It seems just as reasonable for purveyors of optimizing compilers for machines
with memory-mapped IO to have a compiler flag that says "please
be cautious about cacheing things in this routine."
Alternatively, they could accept a #pragma in the code.
It is true that putting volatile in the language encourages
everyone to do the job in the same way, but it is by no means
clear that, on balance, `volatile' makes C a better language.

There is a real cost in having the feature in the language.
It is just one more peculiar thing to learn and be confused
about.  If there is one thing I have learned from reading this
newsgroup, and other popular reactions to C, it is that people
have trouble understanding the language.  Features that do nothing
but request a compiler not to compile your program incorrectly
are not really what C needs.

(I'm especially amused by some of the more extreme positions
stated in favor of `volatile.'  May I be permitted to assert
that it is possible to write a successful operating system
without `volatile,' even on machines with memory-mapped IO?)

I am much more worried about the second justification.  It simply
caters to broken compilers.  Because some machines find it
hard to handle setjmp/longjmp properly, X3J11 ruled that "[following
a longjmp], [a]ll accessible objects have values as of the time
longjmp was called, except that the values of objects of automatic storage
duration that do not have volatile type and have been changed between
the setjmp invocation and longjmp call are indeterminate."
The Rationale is fairly explicit about the apologia.
This is just a botch; the committee should have insisted
that, if necessary, the compiler recognize setjmp and handle its caller
specially.  They edged around this anyway; what other use
is the insistence that setjmp be a macro?  (A footnote in the
Rationale poses this question, too.)

The third hope for volatile, namely shared memory, is in some ways the
most interesting because it nibbles at the edge of mechanisms
that will become more important in the future.  Nevertheless,
as several have pointed out, the Standard conspicuously avoids
the extensions needed to make shared memory work
(e.g. semaphores).  The dpANS even says, "what constitutes
an access to an object that has volatile-qualified type is
implementation-defined," and the sections that discuss
what volatile actually does mean are correspondingly inexplicit.
If you hope to find in the Standard that "extern volatile mutex; ++mutex"
has an iron-clad meaning, you'll be disappointed.
Thus, using volatile for shared memory may be syntactically
portable, but it is not semantically portable, because it
has no defined semantics.

To summarize, using volatile for device registers is plausible;
using it for longjmp is a rank copout; using it for shared memory
is premature.

Has anyone else noticed that a lot of the more peculiar things that X3J11
has added (volatile, and especially noalias) are there for the
benefit of compiler writers and benchmarkers, and not for the user?
(I know how it happens, though; after all, I invented 'register.')

		Dennis Ritchie
		research!dmr
		dmr at research.att.com



More information about the Comp.lang.c mailing list