C has several ways of storing or referencing variables. These affect the way variables behave. Some of the more common ones are: auto, register, and static.
Auto variables are variables declared within functions that are not static or register types. That is, the auto keyword is the default. Normally, auto variables are created on the application’s stack, although C doesn’t require this. The stack is basically a chunk of memory that is allocated for the application’s use when it is first run. It is a place for temporary storage, with values popped onto and pulled off of the stack in first-in, last-out order (like a stack of plates). Unless you initialize an auto variable, you have no idea what its value is when you first use it. Its value happens to be whatever was in that memory location the previous time it was used. It is important to understand that this includes subsequent calls to a function (i.e., its prior value is not “remembered” the next time you call the function). This is because any subsequent call to a function does not have to produce the same the memory locations for these variables, anymore than you always wind up with the same plate every time you go to the cafeteria.
Register variables are similar to auto types in behavior, but instead of using the usual stack method, a CPU register is used (if available). The exact implementation is CPU and compiler specific. In some case the
register keyword is ignored and a simple auto type is used. CPU registers offer faster access than normal memory so register variables are used to create faster execution of critical code. Typically this includes counters or pointers that are incremented inside of loops. A declaration would like something like this:
register int x;
Static variables are used when you need a variable that maintains its value between function calls. So, if we need a variable that will “appear the way we left it” from the last call, we might use something like this:
static char y;
There is one important difference between auto and static types concerning initialization. If an auto variable is initialized in a function as so:
a is set to
1 each time the function is entered. If you do the same initialization with a static, as in:
static char b=1;
b is set to
1 only on the first call. Subsequent entries into the function would not incur the initialization. If it did reinitialize, what would be the sense of having a static type? This is explained by the fact that a static does not usually use the stack method of storage, but rather is placed at a fixed memory location. Again, C does not require the use of a stack, rather, it is a typical implementation.
Two useful but not very common modifiers are
volatile variable is one that can be accessed or modified by another process or task. This has some very special uses (typically, to prevent an optimizing compiler from being too aggressive with optimizations-more on this later). The
const modifier is used for declaring constants, that is, variables that should not change value. In some instances this is preferred over using
#define as type checking is now available (but you can’t use the two interchangeably).