Err...volatile just tells the compiler not to cache the value in a register, that's it. If you don't understand volatile you really, really are not the kind of programmer who should even think about using it.
This is my understanding of volatile as well: volatile just forces read/write to memory. What a read/write to memory entails is a different story. What happens with no volatile is again another story.
If my understanding is wrong, someone please enlighten me.
"Forcing read/write to memory" is very different from "not caching the value in a register". Optimizations can involve not just caching values in registers, but also reordering operations, calculating things at compile-time and so on.
For a trivial example, see this code:
int f() {
int sum = 0;
for (int i = 0; i < 10; i++) sum += i;
return sum;
}
As you can see from [1], a smart compiler will calculate the sum at compile time and make the function simply return the resulting number (i.e., no loop is generated).
If you make "sum" volatile, the compiler is forced to do the loop[2].