TITLE: the meaning of const volatile (Newsgroups: comp.lang.c++.moderated, 5 Oct 96) CUTHBERT: dacut@ugcs.caltech.edu (David A. Cuthbert) > Antonio Fatela wrote: > >At 10.3 of April DWP, there is a reference to 'const volatile' > >cv-qualifier. Whats the meaning of declaring an object as const volatile? > > My understanding of it is to provide read-only access to a > memory-based register. KANZE: kanze@gabi-soft.fr (J. Kanze) This is one of the principal uses. It is not really the meaning, as such. CUTHBERT: > For example, let a communications read port exist at 0x300; writing to > the port will change the status of the port (link rate, etc.), and > would probably corrupt the stream. Therefore, some read function > might contain: > > const volatile char p = *(char *)(0x300); > > The catch is that every time I do an access on p another character is > removed from the port. In other words, code like: > > if(p == 'a') cout << "a "; > else cout << "!a "; > > if(p == 'a') cout << "a "; > else cout << "!a "; > > is *not* guaranteed to print out "a a" or "!a !a", but can print > "a !a" or "!a a". > > To the compiler, volatile directs it to make no optimization > assumptions on that variable. In my experience, there is rarely a > need for it except on embedded systems. KANZE: This is a good example. More precisely: in a const volatile, both const and volatile have their full meaning. Strictly speaking, the exact meaning of volatile is implementation dependant; the intent is to tell the compiler that the variable may change in ways not visible to it. (Memory mapped IO ports are a good example. So are variables that may be modified by asynchronous events, e.g. in signals or by another process or thread.) The effect is (or should be), exactly what you say: the compiler will not optimize code using that variable. (In standardese: there should be a one to one correspondance between the abstract machine and the actual semantics.) Adding const does not change the meaning of volatile in any way. It does mean that the compiler will consider the variable non-modifiable, and will generate an error on any attempt by the program to modify it. It doesn't remove the effect of volatile, however. The compiler should still consider that the value of the variable may change in ways unknown to it. Variants on the above example (memory mapped IO) probably account for 99% of its use; another possible use would be in shared memory (between processes) where the memory is mapped read only for one of the processes. Although the typical low level use makes such occasions rare, any time you have a function which takes a X const&, and the value of the parameter may change asynchronously (in a signal handler or another thread), you should declare it X const volatile&. In practice, such cases don't occur in threads because if X is a simple type, you will use pass by value, and if it is a complex type, you will use some sort of external locking to ensure that it doesn't change when you are in the middle of accessing it.