Professional Documents
Culture Documents
In computer programming, particularly in the C, C++, C#, and Java programming languages,a variable or object declared with the volatile keyword usually has special properties related to optimization and/or threading. Generally speaking, the volatile keyword is intended to prevent the (pseudo)compiler from applying any optimizations on the code that assume values of variables cannot change "on their own." A wikipedia example of volatile : In this example, the code sets the value stored in foo to 0. It then starts to poll that value repeatedly until it changes to 255:
To prevent the compiler from optimizing code as above, the volatile keyword is used: static volatile int foo; void bar (void) { foo = 0; while (foo != 255) ; } With this modification the loop condition will not be optimized away, and the system will detect the change when it occurs. An article from www.linuxforu.com Demystifying the Volatile Keyword in C : Most programmers dont understand the meaning and significance of the volatile keyword. So lets explore that in this months 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 volatileif so, what is its meaning? I bet most of you dont 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
@Articles on Volatile
Usually, hardware has a timer that can be accessed from a memory location. Here, assume that its 00000ABCD 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 stupidit 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 loopwhen 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 ) nothing here */ }
/* do
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 dereferenced 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:
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:
ok here is the comment made by others about logical flaw in ur explanation: 1 person commented: The above link [i gave this link] doesnt answer the question that he asked in the first place. I cant 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 volatileif so, what is its meaning? I bet most of you dont 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 its 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:
@Articles on Volatile
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.
An article by Nigel Jones from www.netrino.com How to Use C's volatile Keyword : Proper use of volatile
A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change: 1. Memory-mapped peripheral registers 2. Global variables modified by an interrupt service routine 3. Global variables accessed by multiple tasks within a multi-threaded application We'll talk about each of these cases in the sections that follow.
Peripheral registers
Embedded systems contain real hardware, usually with sophisticated peripherals. These peripherals contain registers whose values may change asynchronously to the program flow. As a very simple example, consider an 8-bit status register that is memory mapped at address 0x1234. It is required that you poll the status register until it becomes non-zero. The naive and incorrect implementation is as follows:
uint8_t * pReg = (uint8_t *) 0x1234; // Wait for register to become non-zero while (*pReg == 0) { // Do something else
}
5
This will almost certainly fail as soon as you turn compiler optimization on, since the compiler will generate assembly language that looks something like this:
Interrupt service routines often set variables that are tested in mainline code. For example, a serial port interrupt may test each received character to see if it is an ETX character (presumably signifying the end of a message). If the character is an ETX, the ISR might set a global flag. An incorrect implementation of this might be:
int etx_rcvd = FALSE; void main() { ... while (!ext_rcvd) { // Wait } ... }
@Articles on Volatile
Despite the presence of queues, pipes, and other scheduler-aware communications mechanisms in real-time operating systems, it is still fairly common for two tasks to exchange information via a shared memory location (that is, a global). Even as you add a preemptive scheduler to your code, your compiler has no idea what a context switch is or when one might occur. Thus, another task modifying a shared global is conceptually identical to the problem of interrupt service routines discussed previously. So all shared global variables should be declared volatile. For example, this is asking for trouble:
int cntr; void task1(void) { cntr = 0; while (cntr == 0) { sleep(1); } ... } void task2(void)
7
o Final thoughts Some compilers allow you to implicitly declare all variables as volatile. Resist this temptation, since it is essentially a substitute for thought. It also leads to potentially less efficient code. Also, resist the temptation to blame the optimizer or turn it off. Modern optimizers are so good that I cannot remember the last time I came across an optimization bug. In contrast, I come across failures by programmers to use volatile with depressing frequency. If you are given a piece of flaky code to "fix," perform a grep for volatile. If grep comes up empty, the examples given here are probably good places to start looking for problems.
unchanging value and volatile specifies a variable whose value may be changed by processes outside the current program . One example of a volatile object might be a buffer used to exchange data with an external device: check_iobuf(void) { volatile int iobuf; int val; while (iobuf == 0) { } val = iobuf; iobuf = 0; return(val); } if iobuf had not been declared volatile, the compiler would notice that nothing
@Articles on Volatile happens inside the loop and thus eliminate the loop. Here, const and volatile can be used together : o An input only buffer for an external device could be declared as const volatile (or volatile const, order is not important) to make sure the compiler knows that the variable should not be changed (because it is input-only) and that its value may be altered by processes other than the current program.