A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change:
1) A pointer points to a memory mapped hardware registers (for example, status registers)
2) Non-automatic variables which can be modified by an interrupt service routine
3) Shared variables within a multi-threaded application
UINT1 * ptr = (UINT1 *) 0x1234; // Wait for register to become non-zero. while (*ptr == 0); // Do something else.
should be changed to
UINT1 volatile * ptr = (UINT1 volatile *) 0x1234;
the meaning is: ptr point to a variable that may be unexpectedly modified, so every time when we deference it(*ptr), we need to actually retrieve data from its memory address.