Objects and variables with static storage duration exist for the entire duration of a program's execution. They are informally called global variables, globals and static objects.
All objects declared with file scope have static storage,
i.e., anything not
inside a function body. Objects declared
inside a function, but with static
or
extern
, also have static
storage. String
literals are arrays with static storage. Compound
literals outside of function bodies also have static
storage.
The address of a static object can serve as a constant expression.
Here are some declarations for objects with static storage:
// outside of any function
// a tentative definition, with external linkage
int counter;
// a concrete definition, with external linkage
int nombrilo = 100;
// a declaration only, with external linkage
extern int other_counter;
// a concrete definition, with internal linkage
static int counter3 = 100;
// a tentative definition only, with internal linkage
static int counter4;
void func(void)
{
// a definition with block scope for an object with internal linkage
static const char int_msg[] = "message";
// a declaration with block scope for an object with external linkage
extern const char ext_msg[];
/* The function is passed the address of an anonymous
static array of 9 char
s. */
printf("Welcome!\n");
}
All static objects are zero-initialized when the program
starts, unless they have a specific initializer. If a
declaration has an initializer, it is a concrete
definition: nombrilo
,
counter3
, int_msg
. If it lacks an initializer and
extern
, and has file scope, it is a
tentative definition: counter
, counter4
.
Otherwise, it is just a declaration: other_counter
, ext_msg
. At
the end of a translation unit, if a given object has
tentative definitions, there must be at most one
corresponding concrete definition. If one is not provided, a
zero-initialized concrete definition will be assumed.
int counter; // okay; tentative definition int counter; // okay; repeated tentative definition int counter = 10; // okay; concrete definition int counter; // okay; repeated tentative definition extern int counter; // okay; pure declaration extern int counter = 10; // error; repeated concrete definition int counter = 10; // error; repeated concrete definition int counter = 20; // error; conflicting concrete definition extern int counter = 20; // error; conflicting concrete definition