Namespaces
Variants
Views
Actions

Difference between revisions of "c/language/initialization"

From cppreference.com
< c‎ | language
(adopt zero initialization from C++)
 
(6 intermediate revisions by 4 users not shown)
Line 8: Line 8:
 
{{sdsc begin}}
 
{{sdsc begin}}
 
{{sdsc|num=1|1=
 
{{sdsc|num=1|1=
{{ttb|{{=}}}} {{spar|expression}}
+
{{ttb|1==}} {{spar|expression}}
 
}}
 
}}
 
{{sdsc|num=2|1=
 
{{sdsc|num=2|1=
{{ttb|{{=}}}} {{ttb|{}} {{spar|initializer-list}} {{ttb|}<nowiki/>}}
+
{{ttb|1==}} {{ttb|{}} {{spar|initializer-list}} {{ttb|}<nowiki/>}}
 +
}}
 +
{{sdsc|num=3|notes={{mark since c23}}|1=
 +
{{ttb|1==}} {{ttb|{}} {{ttb|}<nowiki/>}}
 
}}
 
}}
 
{{sdsc end}}
 
{{sdsc end}}
  
where {{spar|initializer-list}} is a non-empty comma-separated list of {{spar|initializer}}s (with an optional trailing comma), where each initializer has one of three possible forms:
+
where {{spar|initializer-list}} is a non-empty comma-separated list of {{spar|initializer}}{{sep}}s (with an optional trailing comma), where each initializer has one of three possible forms:
  
 
{{sdsc begin}}
 
{{sdsc begin}}
Line 24: Line 27:
 
{{ttb|{}} {{spar|initializer-list}} {{ttb|}<nowiki/>}}
 
{{ttb|{}} {{spar|initializer-list}} {{ttb|}<nowiki/>}}
 
}}
 
}}
{{sdsc|num=3|1=
+
{{sdsc|num=3|notes={{mark since c23}}|1=
{{spar|designator-list}} {{ttb|{{=}}}} {{spar|initializer}} | notes={{mark since c99}} }}
+
{{ttb|{}} {{ttb|}<nowiki/>}}
 +
}}
 +
{{sdsc|num=4|notes={{mark since c99}}|1=
 +
{{spar|designator-list}} {{ttb|1==}} {{spar|initializer}}
 +
}}
 
{{sdsc end}}
 
{{sdsc end}}
  
 
{{rrev|since=c99|
 
{{rrev|since=c99|
where {{spar|designator-list}} is a list of either array designators of the form {{ttb|[}} {{spar|constant-expression}} {{ttb|]}} or struct/union member designators of the form {{ttb|.}} {{spar|identifier}}; see  
+
where {{spar|designator-list}} is a list of either array designators of the form {{ttb|[}} {{spar|constant-expression}} {{ttb|]}} or struct/union member designators of the form {{ttb|.}} {{spar|identifier}}{{sep}}; see  
 
{{rlp|array initialization}} and {{rlp|struct initialization}}.
 
{{rlp|array initialization}} and {{rlp|struct initialization}}.
  
 
Note: besides initializers, brace-enclosed {{spar|initializer-list}} may appear in {{rlp|compound literal}}s, which are expressions of the form:
 
Note: besides initializers, brace-enclosed {{spar|initializer-list}} may appear in {{rlp|compound literal}}s, which are expressions of the form:
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc | {{ttb|(}} {{spar|type}} {{ttb|)}} {{ttb|{}} {{spar|initializer-list}} {{ttb|}<nowiki/>}} }}
+
{{sdsc | notes=<nowiki/> | {{ttb|(}} {{spar|type}} {{ttb|)}} {{ttb|{}} {{spar|initializer-list}} {{ttb|}<nowiki/>}} }}
 +
{{sdsc | notes={{mark since c23}} | {{ttb|(}} {{spar|type}} {{ttb|)}} {{ttb|{}} {{ttb|}<nowiki/>}} }}
 
{{sdsc end}}
 
{{sdsc end}}
 
}}
 
}}
Line 50: Line 58:
 
If an initializer is not provided:
 
If an initializer is not provided:
 
* objects with automatic {{rlp|storage duration}} are initialized to indeterminate values (which may be {{rlp|object|trap representations}})
 
* objects with automatic {{rlp|storage duration}} are initialized to indeterminate values (which may be {{rlp|object|trap representations}})
* objects with static and thread-local {{rlp|storage duration}} are zero-initialized
+
* objects with static and thread-local {{rlp|storage duration}} are empty-initialized
  
====Zero initialization====
+
====Empty initialization====
In some cases, an object is zero-initialized if it is not initialized explicitly, that is:
+
{{rrev|since=c23|
 +
An object is empty-initialized if it is explicitly initialized from initializer {{c|1== {} }}.
 +
}}
 +
 
 +
In some cases, an object is empty-initialized if it is not initialized explicitly, that is:
 
* pointers are initialized to null pointer values of their types
 
* pointers are initialized to null pointer values of their types
 
* objects of integral types are initialized to unsigned zero
 
* objects of integral types are initialized to unsigned zero
 
* objects of floating types are initialized to positive zero
 
* objects of floating types are initialized to positive zero
* all elements of arrays, all members of structs, and the first members of unions are zero-initialized, recursively, plus all padding bits are initialized to zero
+
* all elements of arrays, all members of structs, and the first members of unions are empty-initialized, recursively, plus all padding bits are initialized to zero
 
:(on platforms where null pointer values and floating zeroes have all-bit-zero representations, this form of initialization for statics is normally implemented by allocating them in the .bss section of the program image)
 
:(on platforms where null pointer values and floating zeroes have all-bit-zero representations, this form of initialization for statics is normally implemented by allocating them in the .bss section of the program image)
  
Line 69: Line 81:
 
If an indeterminate value is used as an argument to any standard library call, the behavior is undefined. Otherwise, the result of any expression involving indeterminate values is an indeterminate value (e.g. {{c|int n;}}, {{c|n}} may not compare equal to itself and it may appear to change its value on subsequent reads)
 
If an indeterminate value is used as an argument to any standard library call, the behavior is undefined. Otherwise, the result of any expression involving indeterminate values is an indeterminate value (e.g. {{c|int n;}}, {{c|n}} may not compare equal to itself and it may appear to change its value on subsequent reads)
  
The term ''zero initialization'' is not used in C standard. It is adopted from [[cpp/language/zero initialization|C++ standard]] and used here for convenience of explanation.
+
{{rrev multi
 
+
|rev1=
There is no special construct in C corresponding [[cpp/language/value initialization|value initialization]] in C++, however, {{c|1== {0} }}{{rev inl|since=c99| (or {{c|1=(T){0} }} in compound literals)}} can be used instead, as C standard does not allow empty structs, empty unions, or arrays of zero length.
+
There is no special construct in C corresponding to [[cpp/language/value initialization|value initialization]] in C++; however, {{c|1== {0} }}{{rev inl|since=c99| (or {{c|1=(T){0} }} in compound literals)}} can be used instead, as the C standard does not allow empty structs, empty unions, or arrays of zero length.
 +
|since2=c23|rev2=
 +
The empty initializer {{c|1== {} }} (or {{c|(T){} }} in compound literals) can be used to achieve the same semantics as [[cpp/language/value initialization|value initialization]] in C++.
 +
}}
  
 
===Example===
 
===Example===
Line 104: Line 119:
  
 
===References===
 
===References===
 +
{{ref std c17}}
 +
{{ref std | section=6.7.9 | title=Initialization | p=100-105}}
 +
{{ref std end}}
 
{{ref std c11}}
 
{{ref std c11}}
 
{{ref std | section=6.7.9 | title=Initialization | p=139-144}}
 
{{ref std | section=6.7.9 | title=Initialization | p=139-144}}
 +
{{ref std end}}
 
{{ref std c99}}
 
{{ref std c99}}
 
{{ref std | section=6.7.8 | title=Initialization | p=125-130}}
 
{{ref std | section=6.7.8 | title=Initialization | p=125-130}}
 +
{{ref std end}}
 
{{ref std c89}}
 
{{ref std c89}}
 
{{ref std | section=6.5.7 | title=Initialization}}
 
{{ref std | section=6.5.7 | title=Initialization}}
Line 114: Line 134:
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc see cpp | cpp/language/initialization |Initialization}}
+
{{dsc see cpp | cpp/language/initialization |Initialization | nomono=true}}
 
{{dsc end}}
 
{{dsc end}}
  
 
{{langlinks|ar|cs|de|es|fr|it|ja|ko|pl|pt|ru|tr|zh}}
 
{{langlinks|ar|cs|de|es|fr|it|ja|ko|pl|pt|ru|tr|zh}}

Latest revision as of 09:03, 26 January 2023

A declaration of an object may provide its initial value through the process known as initialization.

For each declarator, the initializer, if not omitted, may be one of the following:

= expression (1)
= { initializer-list } (2)
= { } (3) (since C23)

where initializer-list is a non-empty comma-separated list of initializer s (with an optional trailing comma), where each initializer has one of three possible forms:

expression (1)
{ initializer-list } (2)
{ } (3) (since C23)
designator-list = initializer (4) (since C99)

where designator-list is a list of either array designators of the form [ constant-expression ] or struct/union member designators of the form . identifier ; see array initialization and struct initialization.

Note: besides initializers, brace-enclosed initializer-list may appear in compound literals, which are expressions of the form:

( type ) { initializer-list }
( type ) { } (since C23)
(since C99)

Contents

[edit] Explanation

The initializer specifies the initial value stored in an object.

[edit] Explicit initialization

If an initializer is provided, see

[edit] Implicit initialization

If an initializer is not provided:

[edit] Empty initialization

An object is empty-initialized if it is explicitly initialized from initializer = {}.

(since C23)

In some cases, an object is empty-initialized if it is not initialized explicitly, that is:

  • pointers are initialized to null pointer values of their types
  • objects of integral types are initialized to unsigned zero
  • objects of floating types are initialized to positive zero
  • all elements of arrays, all members of structs, and the first members of unions are empty-initialized, recursively, plus all padding bits are initialized to zero
(on platforms where null pointer values and floating zeroes have all-bit-zero representations, this form of initialization for statics is normally implemented by allocating them in the .bss section of the program image)

[edit] Notes

When initializing an object of static or thread-local storage duration, every expression in the initializer must be a constant expression or string literal.

Initializers cannot be used in declarations of objects of incomplete type, VLAs, and block-scope objects with linkage.

The initial values of function parameters are established as if by assignment from the arguments of a function call, rather than by initialization.

If an indeterminate value is used as an argument to any standard library call, the behavior is undefined. Otherwise, the result of any expression involving indeterminate values is an indeterminate value (e.g. int n;, n may not compare equal to itself and it may appear to change its value on subsequent reads)

There is no special construct in C corresponding to value initialization in C++; however, = {0} (or (T){0} in compound literals)(since C99) can be used instead, as the C standard does not allow empty structs, empty unions, or arrays of zero length.

(until C23)

The empty initializer = {} (or (T){} in compound literals) can be used to achieve the same semantics as value initialization in C++.

(since C23)

[edit] Example

#include <stdlib.h>
int a[2]; // initializes a to {0, 0}
int main(void)
{
    int i;          // initializes i to an indeterminate value
    static int j;   // initializes j to 0
    int k = 1;      // initializes k to 1
 
    // initializes int x[3] to 1,3,5
    // initializes int* p to &x[0]
    int x[] = { 1, 3, 5 }, *p = x;
 
    // initializes w (an array of two structs) to
    // { { {1,0,0}, 0}, { {2,0,0}, 0} }
    struct {int a[3], b;} w[] = {[0].a = {1}, [1].a[0] = 2};
 
    // function call expression can be used for a local variable
    char* ptr = malloc(10);
    free(ptr);
 
//  Error: objects with static storage duration require constant initializers
//  static char* ptr = malloc(10);
 
//  Error: VLA cannot be initialized
//  int vla[n] = {0};
}

[edit] References

  • C17 standard (ISO/IEC 9899:2018):
  • 6.7.9 Initialization (p: 100-105)
  • C11 standard (ISO/IEC 9899:2011):
  • 6.7.9 Initialization (p: 139-144)
  • C99 standard (ISO/IEC 9899:1999):
  • 6.7.8 Initialization (p: 125-130)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 6.5.7 Initialization

[edit] See also

C++ documentation for Initialization