One example of what @Hodor probably meant by "By using the volatile keyword you're telling the compiler to be very careful about assumptions it might otherwise make":
Code:
int a;
volatile int b;
void f( void ) { a |= 0; }
void g( void ) { b |= 0; }
If you compile this with good optimization and take a look at f() ang g() code, you'll see:
Code:
f:
ret
g:
mov eax,[b]
mov [b],eax
ret
Notice ORing an integer with 0 do nothing... Since 'a' isn't volatile the compiler assumes it doen't change outside the code (by an interruption or if it is an controller register, for example), so there is no need to do the ORing... But 'b' is volatile, so the compiler don't assume the value will be the same always and the copy is made.