Joy of Programming: Demystifying the ‘Volatile’ Keyword in C

17
6758
Most programmers don’t understand the meaning and significance of the ‘volatile’ keyword. So let’s explore that in this month’s Joy of Programming.

One of my favourite interview questions for novice programmers is: “What is the use of the ‘volatile’ keyword?” For experienced programmers, I ask: “Can we qualify a variable as both ‘const’ and ‘volatile’—if so, what is its meaning?” I bet most of you don’t know the answer, right?

The keyword ‘volatile’ is to do with compiler optimisation. Consider the following code:

long *timer = 0x0000ABCD;
// assume that at location 0x0000ABCD the current time is available
long curr_time = *timer;
// initialize curr_time to value from ‘timer’
// wait in while for 1 sec (i.e. 1000 millisec)
while( (curr_time - *timer) < 1000 )
{
    curr_time = *timer; // update current time
}
print_time(curr_time);
// this function prints the current time from the
// passed long variable

Usually, hardware has a timer that can be accessed from a memory location. Here, assume that it’s 0x0000ABCD and is accessed using a long * variable ‘timer’ (in the UNIX tradition, time can be represented as a long variable and increments are done in milliseconds). The loop is meant to wait one second (or 1,000 milliseconds) by repeatedly updating curr_time with the new value from the timer. After a one second delay, the program prints the new time. Looks fine, right?

However, from the compiler point of view, what the loop does is stupid—it repeatedly assigns curr_time with *timer, which is equivalent to doing it once outside the loop. Also, the variable ‘timer’ is de-referenced repeatedly in the loop—when it is enough to do it once. So, to make the code more efficient (i.e., to optimise it), it may modify loop code as follows:

curr_time = *timer; // update current time
long temp_time = *timer;
while( (curr_time - temp_timer) < 1000 )
{   /* do nothing here */
}

As you can see, the result of this transformation is disastrous: the loop will never terminate because neither is curr_time updated nor is the timer de-referenced repeatedly to get new (updated time) values.

What we need is a way to tell the compiler not to ‘play around’ with such variables by declaring them volatile, as in:

    volatile long * timer = 0x0000ABCD;
    volatile curr_time = *timer;

Now, the compiler will not do any optimisation on these variables. This, essentially, is the meaning of the ‘volatile’ keyword: It declares the variables as ‘asynchronous’ variables, i.e., variables that are ‘not-modified-sequentially’. Implicitly, all variables that are not declared volatile are ‘synchronous variables’.

How about qualifying a variable as both const and volatile? As we know, when we declare a variable as const, we mean it’s a ‘read-only’ variable—once we initialise it, we will not change it again, and will only read its value. Here is a modified version of the example:

long * const timer = 0x0000ABCD;
// rest of the code as it was before..

We will never change the address of a timer, so we can put it as a const variable. Now, remember what we did to declare the timer as volatile:

volatile long * timer = 0x0000ABCD;

We can now combine const and volatile together:

volatile long * const timer = 0x0000ABCD;

It reads as follows: the timer is a const pointer to a long volatile variable. In plain English, it means that the timer is a variable that I will not change; it points to a value that can be changed without the knowledge of the compiler!

17 COMMENTS

  1. I am not a programmer but still I enjoyed going through your blog and finding about the volatile keys.
    Good post … It has given me an idea about programming…
    Keep posting…..

  2. I m relieved to find such good work after going through such pains in searching for the appropriate matter for my project……. Congratulations.

  3. Can you please keep posting more and more about this topic? I think it is very useful for all those who find it difficult in searcjing interent. Your blog is a boon for all such people.

  4. Keyword makes your search easy!!! It is easy to find your search if you are sure with your keywords. This blog helped me in giving various ideas about keyword search.

  5. Hey great post. This is really helpful. I wanted some more information on this. Can you please enlighten me a little bit more on this matter. I am waiting for your reply……

  6. Wow this is a really good article. I m glad to have read it. I m looking forward for more of your articles……. I really enjoyed reading it. It’s good to know that there is much more knowledge to gain on this topic. Just keep posting your good work and keep enlightening your readers. Thank you..

  7. Hey great job you have done here. I am glad to have read your post. I still didn’t find the answer to this question “Can we qualify a variable as both ‘const’ and ‘volatile’' ?

  8. Hey SG, I think u make a big blunder by posting such a low quality article. Recently this article was reviewed by many members in an orkut community n some ppl have find out logical mistakes in this article.
    Hw such an article got published in Linux magazine….r there no reviewers?
    If any one wants link to this article review, send me a mail.

  9. >> “Can we qualify a variable as both ‘const’ and ‘volatile’’ ?
    Yes, we can quality a variable as both const and volatile, as in const volatile int i = 10;
    In this case, we cannot modify the value of i, as in
    i = 20;
    we’ll get a compiler error like this “error: assignment of read-only variable ‘i’”

    >> Recently this article was reviewed by many members in an orkut community n
    >> some ppl have find out logical mistakes in this article.
    Rajiv, can you be specific- what specific logical mistake is there? (And its amusing to know that it is “reviewed” in “orkut”!! )

    Ganesh

  10. One level further, the volatile qualifier forces the compiler to generate instructions to fetch the variable (or const) from memory- rather than use the processor register for computation(as an example)

  11. ok here is the comment made by others abt logical flaw in ur explanation:
    1 person commented:
    “The above link[i gave this link] doesn’t answer the question that he asked in the first place. I can’t believe that he is writing a book. Well when people like Yashwant Kanitkar can write a book am sure anyone else can.

    His question was “For experienced programmers, I ask: “Can we qualify a variable as both ‘const’ and ‘volatile’—if so, what is its meaning?” I bet most of you don’t know the answer, right? ”

    And he ends up answering like this:

    “How about qualifying a variable as both const and volatile? As we know, when we declare a variable as const, we mean it’s a ‘read-only’ variable—once we initialise it, we will not change it again, and will only read its value. Here is a modified version of the example:

    long * const timer = 0x0000ABCD;
    // rest of the code as it was before..

    We will never change the address of a timer, so we can put it as a const variable. Now, remember what we did to declare the timer as volatile:

    volatile long * timer = 0x0000ABCD;

    We can now combine const and volatile together:

    volatile long * const timer = 0x0000ABCD;

    But he forgot that he is not using const and volatile on the same variable. In his example what is being pointed to is volatile while what he is using to point is const. That is very different from the question that he asked.”

    Here u r declaring timer as const pointer to long; as its a const pointer, timer cant be changed to point to some other location in the program but the pointed to value can be changed…..isn’t it?

    more flaws in next post…..

  12. ok here is the comment made by others abt logical flaw in ur explanation:
    1 person commented:

    As the author is saying:

    We can now combine const and volatile together:

    volatile long * const timer = 0x0000ABCD;

    But he forgot that he is not using const and volatile on the same variable. In his example what is being pointed to is volatile while what he is using to point is const. That is very different from the question that he asked.”

    Here u r declaring timer as const pointer to long; as its a const pointer, timer cant be changed to point to some other location in the program but the pointed to value can be changed…..isn’t it?

    more flaws in next post…..

  13. I agree with Rajiv..

    Ganesh,

    Your question is misleading, With the question , everyone will think that how a same variable can be volatile and const. But you are making the pointer as constant and value as volatile.

  14. Hi Ganesh,

    I dont know wht pros will say, but I am noob here…… Although i know wht volatile does and const does… but together as their application is something new to me… it was good learning… :)

  15. hi Ganesh,

    int main()
    {
    int a =10;
    printf(” %d %d %d %dn”,++a,a++,a,++a);
    }

    output:- 13 11 13 13

    if i declare volatile int a =10;

    output:- 13 11 11 11.

    generated code was on ubuntu.

    can you please explain me the reason for that(at low level).

LEAVE A REPLY

Please enter your comment!
Please enter your name here