Previous Page
Next Page

11.6. Initialization

You can explicitly specify an object's initial value by including an initializer in its definition. An object defined without an initializer either has an undetermined initial value, or is implicitly initialized by the compiler.

11.6.1. Implicit Initialization

Objects with automatic storage duration have an undetermined initial value if their definition does not include an initializer. Function parameters, which also have automatic storage duration, are initialized with the argument values when the function call occurs. All other objects have static storage duration, and are implicitly initialized with the default value 0, unless their definition includes an explicit initializer. Or, to put it more exactly:

  1. Objects with an arithmetic type have the default initial value 0.

  2. The default initial value of pointer objects is a null pointer (see "Initializing Pointers" in Chapter 9).

The compiler applies these rules recursively in initializing array elements, structure members, and the first members of unions.

11.6.2. Explicit Initialization

An initializer in an object definition specifies the object's initial value explicitly. The initializer is appended to the declarator for the object's identifier with an equals sign (=). The initializer can be either a single expression or a list of initializer expressions enclosed in braces.

For objects with a scalar type, the initializer is a single expression:

    #include <string.h>                // Prototypes of string functions.
    double var = 77, *dPtr = &var;
    int (*funcPtr)( const char*, const char* ) = strcmp;

The initializers here are 77 for the variable var, and &var for the pointer dPtr. The function pointer funcPtr is initialized with the address of the standard library function strcmp( ).

As in an assignment operation, the initializer must be an expression that can be implicitly converted to the object's type. Thus in the previous example, the constant value 77, with type int, is implicitly converted to the type double.

Objects with an array, structure or union type are initialized with a comma-separated list containing initializers for their individual elements or members:

    short a[4] = { 1, 2, 2*2, 2*2*2 };
    Rectangle_t rect1 = { { -1, 1 }, { 1, -1 } };

The type Rectangle_t used here is the typedef name of the structure we defined in Example 11-1, whose members are structures with the type Point_t.

The initializers for objects with static storage duration must be constant expressions, as in the previous examples. Automatic objects are not subject to this restriction. You can also initialize an automatic structure or union object with an existing object of the same type:

    #include <string.h>                   // Prototypes of string functions.
    /* ... */
    void  func( const char *str )
      size_t len = strlen( str );         // Call a function to initialize len.
      Rectangle_t rect2 = rect1;          // Refers to rect1 from the previous
                                          // example.
      /* ... */

More details on initializing arrays, structures and unions, including the initialization of strings and the use of element designators, are presented in "Initializing Arrays" in Chapter 8, and in "Initializing Structures" and "Initializing Unions" in Chapter 10.

Objects declared with the type qualifier const ordinarily must have an initializer, as you can't assign them the desired value later. However, a declaration that is not a definition, such as the declaration of an external identifier, must not include an initializer. Furthermore, you cannot initialize a variable-length array.

    void func( void )
      extern int n;            // Declaration of n, not a definition.
      char buf[n];             // buf is a variable-length array.
      /* ... */

The declarations of the objects n and buf cannot include initializers.

Previous Page
Next Page