Volatile Variable

From Embedded Systems Learning Academy
Jump to: navigation, search

This famous volatile variable article... Reading this article might just find you a job because C/C++ interviews tend to have this very common question on the list! The textbook definition of a volatile variable is: "Any variable that is subject to change externally should be declared volatile".

This often doesn't click in people's mind on what the volatile keyword actually does. It has to do with the way CPUs work and the way compilers optimize your programs. Let's assume that you are compiling in GCC with optimizations turned on and you're working on a loop until a certain bit is set :

// Assume you have a CPU register called UART_STATUS
// and you expect bit 0 to set sometime in near future
while(UART_STATUS & (1 << 0) == 0) {
 ; // Keep waiting
}

If UART_STATUS variable is not volatile, you've got a potential infinite loop even if the bit sets due to GCC optimization technique. Remember that CPUs have to bring information from MEMORY to REGISTERS and GCC may optimize your code such that MEMORY to REGISTER instruction is minimally used to enhance performance.


Assembly code without volatile:

LOAD R0, &UART_STATUS
LOOP: 
    CHECK R0, BIT0
    JUMP LOOP IF R0

Assembly code *with* volatile:

LOOP: 
    LOAD R0, &UART_STATUS
    CHECK R0, BIT0
    JUMP LOOP IF R0


Compiler Optimization

The compiler basically optimizes the loop taking for granted that the memory variable UART_STATUS is not changing INSIDE the loop, therefore, there is no need for a (re)LOAD from memory instruction inside the loop. Using volatile keyword in this case tells the compiler that the variable is subject to change externally (outside of the context of the loop), therefore it should reload the memory whenever it is referenced.