Broad Network


Storage-class Specifiers in C

Part 35 of the Complete C Course

Foreword: Storage-class Specifiers in C

By: Chrysanthus Date Published: 22 Jun 2024

Introduction

An object is a region in memory that has one or more locations next to one another. When a program ends, the regions for its objects, should be (or should have been) freed to be used by other programs or users. While a program is running, objects are created, and the objects live for some time and die. Not all objects die before the end of the program. Many objects die before the end of the program.

If an object is alive (exists), then it has a starting memory address, and it retains its last stored value. The lifetime of an object is the portion (or duration) of program execution during which, storage is guaranteed to be reserved for it. If an object is referred to, outside of (beyond) its lifetime, the behavior is undefined. The value of a pointer becomes invalid, when the object it points to (or just past) reaches the end of its lifetime.

Type Specifiers
Type specifiers are: void, char, short, int, long, float, double, signed, unsigned, _Bool, typedef, _Complex, and atomic-type-specifier. These specifiers do not determine the duration (life time) of objects. Some of these specifiers have been discussed in this chapter. typedef will be discussed later in this chapter.

Storage-class Specifiers
Storage class specifiers are: auto, static, register, extern, and _Thread_local. These determine the lifetime of an object. Among these, only the static specifier and the register specifier are addressed in this section of the chapter.

Static Specifier
When an object is defined in the ordinary way, it is said to have automatic storage duration. An object with automatic storage duration, dies when it goes out of scope. An object declared with the reserved word static, is a static object. It does not die when it goes out of scope.

Normal Object Operation
Consider the following program, where n is an object of automatic storage duration:

    #include <stdio.h>

    void fn() {
        int n = 0;

        printf("%i\n", n);
          
        n = n + 2;
     }

    int main()
    {
        fn();
        fn();
        fn();
        fn();

        return 0;
    }

The output is four zeros, with each zero on a separate line. In the function, fn(), n is an ordinary integer object. In the C main() function, the function fn() is called 4 times. Each time the function, fn() in the main() function is called, n is reinitialized to zero.  So the value displayed for n from fn() is always zero. After the display (printf statement), in the fn() function definition, n is increased by 2; but this has no effect at the display, the next time fn() is called. This increase of n, and n as a whole, die (is annulled) at the very end of the function block. To prevent this death, make n static.

Static Object
If in the fn() function definition above, n where made static, then n will be initialized only when the function is called for the first time. If a static object is not initialized for the first time, the object takes the default value. In the case of integer, the default value is 0. That is one of the characteristics of a static object. Another characteristic of a static object is that it does not die when it goes out of scope. So, for a static object, if the scope (function definition) is re-executed, the previous value of the static object will be maintained. To define a static object, precede the normal definition with the reserved word, static. Read and test the following program:

    #include <stdio.h>

    void fn()
    {
        static int n = 0;

        printf("%i\n", n);
        
        n = n + 2;
    }

    int main()
    {
        fn();
        fn();
        fn();
        fn();

        return 0;
    }

In the fn() function, n is now a static object. The first time the fn() function is called from the main() function, n is initialized to zero. Then n is displayed. Then n is increased by 2 and the function block goes out of scope. Since the value of a static object does not die when it goes out of scope, the last value of n is retained by n itself.

The next time, the function, fn() is called, n is no longer initialized; that is, the initialization statement is skipped. Initialization for a static object is done only once. After the skipping, n is displayed, and then n is increased by 2 on its previous value. So, the output of the above code is, 0, 2, 4, 6, in new lines.

So, a static object is an object that is initialized only once, if its scope block is executed many times; and it is an object that does not die when it goes out of scope.

The initialization of a static object should not be broken down into declaration and assignment (initialization).

Not Accessible out of Scope
Though a static object does not die, when it goes out of scope, it cannot be accessed out of scope. On the other hand, a file scope object can be seen in any scope. A file scope object is usually an automatic storage object that is not declared in any block or in any parentheses.

register
A declaration of an identifier for an object with storage-class specifier, register, suggests that access to the object should be as fast as possible. The extent to which such a suggestion is effective, is implementation-defined.



Related Links

More Related Links

Cousins

BACK NEXT

Comments