Storage Classes in C Programming Language

Storage class specifiers are the keywords which can appear next to the top-level type of a declaration. The use of these keywords affects the storage duration and linkage of the declared object, depending on whether it is declared at file scope or at block scope:

1. auto

This storage class denotes that an identifier has automatic storage duration. This means once the scope in which the identifier was defined ends, the object denoted by the identifier is no longer valid.

Since all objects, not living in global scope or being declared static, have automatic storage duration by default when defined, this keyword is mostly of historical interest and should not be used:

int foo(void)
{
/* An integer with automatic storage duration. */
auto int i = 3;
/* Same */
int j = 5;
return 0;
} /* The values of i and j are no longer able to be used. */

2. register

Hints to the compiler that access to an object should be as fast as possible. The register storage class is more appropriate for variables that are defined inside a block and are accessed with high frequency. For example,

In C11, The _Alignof operator is also allowed to be used with register arrays.

3. extern

Used to declare an object or function that is defined elsewhere (and that has external linkage). In general, it is used to declare an object or function to be used in a module that is not the one in which the corresponding object or function is defined:

Things get slightly more interesting with the introduction of the inline keyword in C99:

Hints to the compiler that the function bar might be inlined and suppresses the generation of an external symbol, unless stated otherwise.

/* Should usually be place in a header file such that all users see the definition */
inline void bar(int drink)
{
printf("You ordered drink no.%d\n", drink);
}

To be found in just one .c file. Creates an external function definition of bar for use by other files. The compiler is allowed to choose between the inline version and the external definition when bar is called. Without this line, bar would only be an inline function, and other files would not be able to call it.

extern void bar(int);

4. static

The static storage class serves different purposes, depending on the location of the declaration in the file:

To confine the identifier to that translation unit only (scope=file).

/* No other translation unit can use this variable. */
static int i;
/* Same; static is attached to the function type of f, not the return type int. */
static int f(int n);

5. _Thread_local

This was a new storage specifier introduced in C11 along with multi-threading. This isn't available in earlier C standards.

Denotes thread storage duration. A variable declared with _Thread_local storage specifier denotes that the object is local to that thread and its lifetime is the entire execution of the thread in which it's created. It can also appear along with static or extern.

6. typedef

Defines a new type based on an existing type. Its syntax mirrors that of a variable declaration.

/* Byte can be used wherever `unsigned char` is needed */
typedef unsigned char Byte;
/* Integer is the type used to declare an array consisting of a single int */
typedef int Integer[1];
/* NodeRef is a type used for pointers to a structure type with the tag "node" */
typedef struct node *NodeRef;
/* SigHandler is the function pointer type that gets passed to the signal function. */
typedef void (*SigHandler)(int);

While not technically a storage class, a compiler will treat it as one since none of the other storage classes are allowed if the typedef keyword is used.

The typedefs are important and should not be substituted with #define macro.

Share this Article

0

shares

Subscribe to Developer Insider

Get the latest posts delivered right to your inbox.

Vineet Choudhary — I love building applications for mobile and desktop. I am always interested in learning new and better ways of doing things. Open content and exchange of information is something I am interested in.