Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a string literal count as a partial initializer and zero-initialize?

In C, you can partially initialize a struct or array, with the result that the members/elements that aren't mentioned in the initializer are zero-initialized. (C99 section 6.7.8.19). For example:-

int a[4] = {1, 2};
// a[0] == 1
// a[1] == 2
// a[2] == 0
// a[3] == 0

You can also initialize "an array of character type" with a string literal (C99 section 6.7.8.14), and "successive characters ... initialize the elements of the array". For example:-

char b[4] = "abc";
// b[0] == 'a'
// b[1] == 'b'
// b[2] == 'c'
// b[3] == '\0'

All pretty straightforward. But what happens if you explicitly give the length of the array, but use a literal that's too short to fill the array? Are the remaining characters zero-initialized, or do they have undefined values?

char c[4] = "a";
// c[0] == 'a'
// c[1] == '\0'
// c[2] == ?
// c[3] == ?

Treating it as a partial initializer would make sense, it would make char c[4] = "a" behave exactly like char c[4] = {'a'}, and it would have the useful side-effect of letting you zero-initialize a whole character array concisely with char d[N] = "", but it's not at all clear to me that that's what the spec requires.

like image 556
Dan Hulme Avatar asked Aug 02 '12 15:08

Dan Hulme


People also ask

What happens when you partially initialize an array with values?

If an array is partially initialized, elements that are not initialized receive the value 0 of the appropriate type. The same applies to elements of arrays with static storage duration. (All file-scope variables and function-scope variables declared with the static keyword have static storage duration.)

Which of the following is the correct way of initializing a character array?

An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.


2 Answers

 char c[4] = "a";

All the remaining elements of the array will be set to 0. That is, not only c[1] but also c[2] and c[3].

Note that this does not depend on the storage duration of c, i. e., even if c has automatic storage duration the remaining elements will be set to 0.

From the C Standard (emphasis mine):

(C99, 6.7.8p21) "If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration."

like image 115
ouah Avatar answered Oct 18 '22 07:10

ouah


From the C99 standard (as already stated by ouah):

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

and:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:

  • if it has pointer type, it is initialized to a null pointer;
  • if it has arithmetic type, it is initialized to (positive or unsigned) zero;
  • if it is an aggregate, every member is initialized (recursively) according to these rules;
  • if it is a union, the first named member is initialized (recursively) according to these rules.

And char is an arithmetic type, so the remaining elements of the array will be initialised to zero.

like image 42
hmjd Avatar answered Oct 18 '22 05:10

hmjd