A common reason for customers seeking tech support is in response to the compiler not generating code for a specific variable or expression. The situation occurs when a variable in a function is updated outside of the scope of the function or block such as in an interrupt routine. The lack of code generation is due to standard redundant code removal optimizations meaning, the optimizer cannot see that the variable is used or altered and therefore eliminates it to produce the most concise code possible. Using the volatile modifier on the variable in question will alert the optimizer to the fact that this value may be changed during run time by code outside of the variable's normal scope. This will prevent the optimization and the desired code will then be generated. The volatile modifier is placed in the declaration, definition, and prototype and in any external references. It is important that all references have matching modifiers. The volatile modifier is not included however, when the variable is called or used. See "The const and volatile Type Qualifiers" section of the user's manual for more information.
volatile unsigned char SCDR;
extern volatile unsigned char SCDR;
A common mistake is to forget about global variables that are modified by interrupt service routines. These need to be declared as volatile as well as most hardware registers.
Another common mistake is to forget to use the volatile on extern prototypes.