Let's discuss about basic behind a variable.
Any variable if you are declaring then if you are aware about it that someone updated the value, then each time we read the variable then we will get the updated value.
But think about a scenario where variable's value is changing by other means (through interrupt) and before that you have read the value and stored in a temporary register so that you can read each time from this register instead of reading again form the variable's memory location. [As reading from register will be fast, as you already read from memory and stored here it means it is acting like cache]. So when value changed by other means then still the register variable will be same, and you are going to read the old value from register instead of getting new value from the variable's memory location.
If compiler thinks for optimization and do this in the way described then it's problem as you are not getting updated value.So we need to find out some way where we will tell to the compiler that generate instruction in such a way that each time i ask for value you give me the updated variable by reading the memory location instead of reading from register[Where the variable's value may be cached].
So we declare the variable as volatile so that compiler generates instruction in such a way that, each read of the variable will read from memory location so that we can get the updated variable if some one changed [It may be some interrupt routine, or may be by some other thread if it's global variable].
In these scenarios we should declare out variable as volatile.
Hope it is clear.