Shirone's Blog

Volatile in C

When I was reading some C codes from Linux kernel for the first time, I found that a compiler keyword “volatile” is commonly used in some modules. I seldom see or use compiler keywords before, so I did some research on it.

From stack overflow:

volatile tells the compiler not to optimize anything that has to do with the volatile variable. Actually came into existence for the purpose of not caching the values of the variable automatically. It will tell the compiler not to cache the value of this variable.

And I even found some interesting examples

#include <stdio.h>
int main(void)
{
    const int local = 10;
    int *ptr = (int*) &local;

    printf("Initial value: %d \n", local);

    *ptr = 100;
    printf("After modifications: %d \n", local);

    return 0;
}

If we directly compiles the program and run it, the output will be the following on my computer:

Initial value: 10

After modifications: 10

Wow! We modified the integer but the changes are not shown!

Lets have a look on the assembly code. As we can see, we write the number 10 into register x8 and pass it as an argument to the first printf() function. And, we did modified the number, in the red block. But, for our second call to printf(), we still passed the value stores in register x8 without modification.

first_try

How can we solve such problem? We can use the compiler keyword ‘volatile’. Modified line 4 of the above program, we get:

const volatile int local = 10;

The result after modification shows that we did solved such problem.

Initial value: 10

After modifications: 100

Let’s have a look of the assembly code again and see what is changed.

with_volatile

Yes! We did reload the number stored in local before we use it again.

Small tips: w9, x9 are actually the same register in arm. w9 is the 32bit version of x9 and it only use the top 32bit of x9.