In said:
I have read about this qualifier in many books and have read
things like "would not let the compiler optimize" "can be
modified externally" etc. But I am not able to understand it
well.
Could someone give me a small example and explain the
meaning and use of the volatile qualifier.
Consider the following 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;
}
If you compile it with gcc without enabling optimisation, it will work
as expected. With -O2, it will stay forever in the while loop, because
the compiler assumes that the value of gotsig cannot change inside the
loop, so there is no need to check its value more than once: the loop is
either skipped or it becomes an infinite loop.
To avoid this, you must tell to the compiler that it cannot assume that
the value of gotsig cannot change inside the loop (otherwise, a perfectly
reasonable assumption). To achieve this, you declare gotsig like this:
volatile sig_atomic_t gotsig = 0;
Now, the program will work as expected at any optimisation level (at least
as far as gcc is concerned ;-)
Another typical example is a program performing memory tests. Such
programs write certain values to the memory, then read them back and
check to see if they get the same values. From the compiler's point of
view, such an operation is completely pointless: if you write something
you're guaranteed to read back the same value, so it could optimise the
whole code away. To avoid that, you have to either make the pointer
volatile or the object it points to or both, but it's probably more
efficient to make only the object pointed to volatile.
Dan