5.3.8.2 Volatile Type Qualifier

The volatile type qualifier indicates to the compiler that an object cannot be guaranteed to retain its value between successive accesses. This information prevents the optimizer from eliminating apparently redundant references to objects declared volatile because these references might alter the behavior of the program.

Any SFR which can be modified by hardware or which drives hardware is qualified as volatile and any variables which can be modified by interrupt routines should use this qualifier as well. For example:

#include <xc.h>
volatile static unsigned int  TACTL __at(0x160);

The volatile qualifier does not guarantee that the object will be accessed atomically. Because the 8-bit PIC MCU architecture can only access a maximum of 1 byte of data per instruction, reading and writing most objects requires more than one instruction to complete.

The code produced by the compiler, used to access volatile objects can be different to that of ordinary variables and typically the code will be longer and slower for volatile objects, so only use this qualifier if it is necessary. However, failure to use this qualifier when it is required can lead to code failure.

A common use of the volatile keyword is to prevent unused global variables being removed. If a non-volatile variable is never used, or used in a way that has no effect, then it can be removed before code is generated by the compiler.

A C statement that consists only of a volatile variable’s identifier will produce code that reads the variable’s memory location and discards the result. For example, if PORTB; is an entire statement, it will produce assembly code the reads PORTB.

Some variables are treated as being volatile even though their definition might not use the volatile qualifier. This is true for any permanent storage duration object that is referenced in interrupt code, unless they are an initialized object qualified as const. It is also the case for objects defined but not used in C source, and that are accessed in hand-written assembly code. See 5.12.3.6 Undefined Symbols if you have assembly code in your project. It is recommended that in all these case you explicitly mark these variables using the volatile specifier to ensure that the your code is portable and its operation clear.