So far we have considered definition: the variable (or function) is named and enough storage for its type is created. There are times when the compiler needs to know in advance that a definition will appear later, even though it is not possible to make the definition yet. C achieves this with a what it calls a declaration. This is simply a way of saying that, when the definition finally arrives, it will be in this form. The purpose is to allow the compiler to compile code which is incomplete, for example because one file uses a function which is defined in a later file.
For data items, if I write:
char ch;
then that is a definition and storage is created. If instead I write:
extern char ch;
then that is a declaration and no storage is created. It allows the compiler to proceed, knowing that ch will be a char. In general, there can be any number of declarations for a given name (the name may be needed in many files) but precisely one definition (the storage has to be created somewhere and uniquely).
extern is used to indicate a declaration for both functions and for data items; without it you get a definition.
How do we declare and define a function? We declare a function by giving only its prototype. We define a function by giving the body in full.
Example
Here is the skeleton of a program:
...
void f1(int, int); /* Declare f1 */
...
/* Section A */
/* includes a call to f1 */
...
void f1(int i, int j) /* Define f1 */
{
/* Body of f1 here */
}
Note we wanted to make use of f1 before it was defined, so we declared it to bring it in scope. Note also the form of the declaration: there is a semi-colon on the end and only the types of the parameters are needed (so the compiler can type-check or type-convert). If fact, you can name the parameters if you wish but this is optional.
Of course we might have been able to define it before we used it; that is one way of bringing it into scope. This is not always possible (Suppose f1 uses f2 and f2 uses f1) or desirable (it may be easier to maintain the file if the routines are in alphabetical order, or grouped functionally etc).
Here is a multi-purpose example.
Example
int var1; /* This is a definition, external linkage */
extern double var2; /* This is a declaration */
/* var2 must be defined later */
int main ()
{
int var3; /* This is an automatic, scope=main, no linkage */
if (....)
{
int x; /* Automatic, scope=this block, no linkage */
static double y; /* Retains its value outside the block, */
/* internal linkage, cannot be referenced outside */
}
...
}
Notes on storage classes in C
1. `Automatic' tells us the storage is created at run time, within the block, and destroyed on exit.
2. `Static' tells us the storage is permanent but private to the source file or block.
3. You can have static internal or static external.
A static internal item is known within the remainder of the block only, but keeps its value at all times.
A static external item is known within the remainder of the source file only, but keeps its value at all times.
maspjw@