What is the use of volatile keyword in C/C++? What is the difference between declaring a variable volatile
and not declaring it as volatile
?
Volatile tells to compiler that this value might change and the compiler should not do any optimization on it. An example of it.
/** port to read temperature **/
#define PORTBASE 0x40000000
unsigned int volatile * const port = (unsigned int *) PORTBASE;
for(;;)
{
if(*port == 300)
{
/** shutdown the system **/
}
}
If port is not volatile, then the compiler will assume that the value cannot be changed. It will never do the checking if *port == 300. However, the value can be changed based on the sensor. We put volatile to tell compiler that don't do any optimization on it. Thumb rule is when using the memory mapped registers, whose value can change based on the circumstance, then use volatile keyword.
volatile restrict the compiler not to optimize the use of particular variable that is declared volatile in to the code.
Difference between variable with volatile and without it
Variable Without volatile
int main()
{
int a = 5;
while(a == 5) //compiler replace variable **'a'** with 5 as optimization purpose
{
}
if(a==5)//compiler replace **'a'** with 5 as optimization purpose
{
}
return 0;
}
in above code compiler assume that the value of the variable 'a' will always be 5,so compiler replace all 'a' with 5 as optimization purpose.
Variable with volatile
But some variables value changed by outside interrupt,so here we always need to get that variables value directly from Memory.For this purpose we use volatile.
volatile int a=5;
while(a==5) //compiler will npt optimize the variable **'a'** and always get the value of **'a'** from Memory
when we use the simple non volatile variable at that time the compiler will try to optimize the code, for example if you are using b=a*a*a; then it will be used like b=a*3; but when you use the volatile keyword while declaring the variable "a" , then the optimization wont take place for the value of "a", and each and every time the value will be fetched from the memory, because volatile Qualifier will allow other hardware as well as the process to change the value of the variable.
The volatile
qualifier on a variable tells the compiler that whenever you access this variable, its value has to be loaded from memory, and that the compiler may assume nothing about this value from previous stores it has effected.
So it is appropriate whenever you have situations where a variable may have a value that can not be foreseen in the current "thread of execution" (in a broad sense). This includes:
goto
,
switch
/case
, or, more important,
setjmp
/longjmp
.volatile
is also necessary (but not sufficient!) for atomic access to thread shared variables to which the access is not mutexed. For that purpose volatile
is by no means sufficient to guarantee the atomic access, even if it is just for reading. For that, you'd have to use special instructions of the CPU that are not modeled (or interfaced) by the abstract machine of the current C standard, C99. The next standard, C1X, is supposed to have such primitives.
Volatile tells the compiler that the value of variable can be change from outside the scope of your code for ex.
{
int x;
int y;
}
The value of x and y are limited to the scope but in case if we are modifying its value from somewhere outside then it should be marked as volatile because compiler will keep these values in temporary register and always give the same value instead of giving the modified value.
So in such cases volatile must be used in order to get the recent value of that particular variable.
Volatile tells the compiler that the variable might change without it knowing - so it shouldn't optimise it away.
The only time I have ever needed it was in the days of ISA cards when you read a memory address to get the data from the bus. There was also a bug in the compiler which meant volatile didnt work!
It can also be useful in some parallel / mutli-threaded code