www.thecareerplus.com
The CareerPlus
Home Technical Resources Programming Variables and Data types
Wednesday 08th September 2010
 
 
To what does the term storage class refer? What are auto, static, extern, volatile, const classes?

Discuss it!          



This is a part of a variable declaration that tells the compiler how to interpret
the variable's symbol. It does not in itself allocate storage, but it usually tells
the compiler how the variable should be stored. Storage class specifiers help you
to specify the type of storage used for data objects. Only one storage class specifier
is permitted in a declaration this makes sense, as there is only one way of storing
things and if you omit the storage class specifier in a declaration, a default is
chosen. The default depends on whether the declaration is made outside a function
(external declarations) or inside a function (internal declarations). For external
declarations the default storage class specifier will be extern and for internal
declarations it will be auto. The only exception to this rule is the declaration
of functions, whose default storage class specifier is always extern.
Here are C's storage classes and what they signify: * auto - local variables. * static - variables are defined in a nonvolatile region of memory such that they
retain their contents though out the program's execution.
* register - asks the compiler to devote a processor register to this variable in
order to speed the program's execution. The compiler may not comply and the variable
looses it contents and identity when the function it which it is defined terminates.

* extern - tells the compiler that the variable is defined in another module.
In C, const and volatile are type qualifiers. The const and volatile type qualifiers
are completely independent. A common misconception is to imagine that somehow const
is the opposite of volatile and vice versa. This is wrong. The keywords const and
volatile can be applied to any declaration, including those of structures, unions,
enumerated types or typedef names. Applying them to a declaration is called qualifying
the declaration?that's why const and volatile are called type qualifiers, rather
than type specifiers.
* const means that something is not modifiable, so a data object that is declared
with const as a part of its type specification must not be assigned to in any way
during the run of a program. The main intention of introducing const objects was
to allow them to be put into read-only store, and to permit compilers to do extra
consistency checking in a program. Unless you defeat the intent by doing naughty
things with pointers, a compiler is able to check that const objects are not modified
explicitly by the user. It is very likely that the definition of the object will
contain an initializer (otherwise, since you can't assign to it, how would it ever
get a value?), but this is not always the case. For example, if you were accessing
a hardware port at a fixed memory address and promised only to read from it, then
it would be declared to be const but not initialized.
* volatile tells the compiler that other programs will be modifying this variable
in addition to the program being compiled. For example, an I/O device might need
write directly into a program or data space. Meanwhile, the program itself may never
directly access the memory area in question. In such a case, we would not want the
compiler to optimize-out this data area that never seems to be used by the program,
yet must exist for the program to function correctly in a larger context. It tells
the compiler that the object is subject to sudden change for reasons which cannot
be predicted from a study of the program itself, and forces every reference to such
an object to be a genuine reference.
* const volatile - Both constant and volatile. The "volatile" modifier The volatile modifier is a directive to the compiler?s optimizer that operations
involving this variable should not be optimized in certain ways. There are two special
cases in which use of the volatile modifier is desirable. The first case involves
memory-mapped hardware (a device such as a graphics adaptor that appears to the computer?s
hardware as if it were part of the computer?s memory), and the second involves shared
memory (memory used by two or more programs running simultaneously). Most computers
have a set of registers that can be accessed faster than the computer?s main memory.
A good compiler will perform a kind of optimization called ?redundant load and store
removal.? The compiler looks for places in the code where it can either remove an
instruction to load data from memory because the value is already in a register,
or remove an instruction to store data to memory because the value can stay in a
register until it is changed again anyway.
If a variable is a pointer to something other than normal memory, such as memory-mapped
ports on a
peripheral, redundant load and store optimizations might be detrimental. For instance,
here?s a piece of code that might be used to time some operation:
time_t time_addition(volatile const struct timer *t, int a) { int n; int x; time_t then; x = 0; then = t->value; for (n = 0; n < 1000; n++) { x = x + a; } return t->value - then; } In this code, the variable t->value is actually a hardware counter that is being
incremented as time passes. The function adds the value of a to x 1000 times, and
it returns the amount the timer was incremented by while the 1000 additions were
being performed. Without the volatile modifier, a clever optimizer might assume that
the value of t does not change during the execution of the function, because there
is no statement that explicitly changes it. In that case, there?s no need to read
it from memory a second time and subtract it, because the answer will always be 0.
The compiler might therefore ?optimize? the function by making it always return 0.
If a variable points to data in shared memory, you also don?t want the compiler to
perform redundant load and store optimizations. Shared memory is normally used to
enable two programs to communicate with each other by having one program store data
in the shared portion of memory and the other program read the same portion of memory.
If the compiler optimizes away a load or store of shared memory, communication between
the two programs will be affected.

Discuss it!          

CrackTheIntervew.NET
Advertisement
 
Top! Top!