Re: Volatile variables

From: Dan Pop (Dan.Pop_at_cern.ch)
Date: 02/27/04


Date: 27 Feb 2004 15:06:59 GMT

In <ff8ef364.0402270008.36b416b0@posting.google.com> srinivasreddy_m@yahoo.com (srinivas reddy) writes:

>Is there any chance that a program doesn' work properly even after a
>variable is declared as volatile?

If a program was correct before declaring anything as volatile, it will
keep being correct after and will produce the same output, unless the
output depends on unspecified behaviour. The only purpose of volatile is
to dumb down the compiler, WRT certain optimisations otherwise allowed by
the language.

OTOH, there are programs that aren't correct in the absence of the
volatile qualifier and that are fixed this way. Here's an example:

    #include <stdio.h>
    #include <signal.h>

    sig_atomic_t gotsig = 0;

    void handler(int signo)
    {
        gotsig = signo;
    }

    int main()
    {
        signal(SIGINT, handler);
        puts("Press the interrupt key to exit.");
        while (gotsig == 0) ;
        printf ("The program received signal %d.\n", (int)gotsig);
        return 0;
    }

Because gotsig is not volatile, the compiler is free to "optimise" the

    while (gotsig == 0) ;

loop to:

    if (gotsig == 0) while (1) ;

since it sees no way the value of gotsig can change inside the loop.

If gotsig is volatile, the compiler must assume that its value can change
behind its back and keep testing its value.

But this doesn't mean that it's worth trying to fix broken programs by
randomly throwing in volatile qualifiers. As usual, there is no
substitute for knowing what you're doing.

>I remember somebody mentioning a
>scenario involving L1, L2 caches. Could anybody throw some light on
>this?

Whoever mentioned such a scenario was heavily confused and in dire need
of a clue. The abstract C machine has no caching, therefore caching is
irrelevant to the correct behaviour of a C program.

Another typical example of using volatile is when writing memory testing
programs. Such programs often write values in memory and then read them
back and compare with the original. To the compiler, it is obvious what
the result of the comparison should be, so it can optimise all the memory
testing away and declare that the memory works correctly. To force the
writing to and the reading from memory, you *have* to use a pointer to
volatile data.

Dan

-- 
Dan Pop
DESY Zeuthen, RZ group
Email: Dan.Pop@ifh.de


Relevant Pages