Volatile” is a qualifier in C. It is intended to prevent the optimization of the object that can change in manners that cannot be determined by compiler. The best example is the HW registers of the microcontroller.

In very simple words, we can say that by using volatile keyword we are asking the compiler to not optimize the object.
A volatile can solve a very complex, hard to replicate problem in very simple way. Let us first try to understand the problem and then the solution using a volatile keyword.

Problem:
Let us say we have 3 variables x and.

int x = 10;
int y = 20;

int z = 20;

In main loop, somewhere we are updating y with 2*x + y and then z with sum of x and y.
void main(void)
{
while(1)
{
....
y = 2*x + y;
printf("Value of y = %d", y);
...
}
}

In interrupt, we are checking if y >= 100 then we reset value of y.
if (y >= 100)
{
y = 0;
}

This code works fine, but sometimes it is observed that sometimes the value of y does not gets reset.
Can you identify the root cause of the issue?

To find the root cause first let us understand how “y = 2*x + y;" inside the CPU.

  1. Value of x is loaded in register and then multiplied by 2
  2. Value of y is loaded in register
  3. Value of result of step 1 is added to y
  4. The result of step 3 is written to y

If the interrupt comes in-between step 2 and 4 then the issue will get replicated as explained in below picture

image

This issue can become a nightmare as it will be very hard to replicate but might be too frequent in real environment.


Solution
A value of y is getting updated outside the main loop and we cannot predict when it is changing so we should declare y as volatile.

Once the variable y will be declared volatile then the compiler will never optimize it. So, a fresh value of y will be taken on every step. Which will result in reset of y if its value is greater than 100.


Moral: Always make the variable/struct volatile if its value is getting changed in unpredicted manner.