Jingz said:
I've bever used it myself, and without looking it up in the ARM or google
or anything, I seem to recall volitile being used to keep the compiler
from optimizing out necessary code that looks harmless, a simple example
might be a (poorly written) multithreaded program:
The C++ standard doesn't care about multi-threading. Making variables
volatile will not guarantee correct behaviour in a multi-threaded
environment. Unless you know exactly what your compiler does with the
volatile specification and what that means for the execution
environment, the volitile keyword is of little or no use in most cases.
Non volatile variables may loaded at (more or less) arbitratrary times
from memory into a processor register and written back to memory at
(more or less) arbitrary times as well, in the meanwhile the value of
the value may have been changed many times without those changes being
reflected in memory. This optimization is problematic when multiple
threads access the same variable, as they essentially may operate on
their copy of the variable and don't see the changes made by the other
threads. Usually declaring a variable volatile means that the value of a
variable is loaded from memory every time it is needed, and written back
to memory every time its value is changed. However this doesn't
guarantee correct behaviour in a multi-threaded enviroment.
Example:
volatile int v=0;
void ThreadA()
{
for(int i = 0; i < 1000; ++i)
{
++v;
}
}
void ThreadB()
{
for(int i = 0; i < 1000; ++i)
{
++v;
}
}
So the question is what will be the value of 'v' when threads A and B
have completed? The answer is that the value of 'v' can be anything
between 1000 and 2000. This is because the line ++v may very well be
translated to three processor instructions:
mov ecx, [v];// Load value from memory into ecx register.
inc ecx // Increment value of ecx register
mov [v], ecx // Write value back to memory.
The problem is that a thread context switch can occure after every
processor instruction. If thread A loads the value 0 from memory into
ecx, and immediately after that instruction a context switch to thread B
occures thread B will read a 0 value for v as well. Now lets suppose
thread B can complete without a context switches to thread A. In that
case the value of variable v in memory will be 1000 at that point in
time. However when thread A continues it will still have 0 in its ecx
register, and after the first iteration of the loop in thread A the
value of v in memory will go back from 1000 to 1. Consequently when
thread A finishes the value of 'v' will be 1000. This is just one
example what may go wrong.
Moral of this story; for proper thread synchronisation you will have to
rely on the facilities offered by the platform, C++ cannot help you
here.