12

If I write:

char arr[8] = "abc";

Is there any specification over what arr[4] might be? I did some tests with Clang and it seems that the remaining chars in the array are set to null. Also, char arr[8] = ""; zeroes every byte. Not sure if this is a compiler convenience, standard behavior, pure coincidence or I got it wrong.


void a()
{
    char arr[8] = "abc";    /* breakpoint here, line 3 */
    strcpy(arr, "1234567");
}
int main()
{
    a();
    a();
    return 0;
}

Debugger transcript:

Breakpoint 1, a () at str.c:3
3           char arr[8] = "abc";
(gdb) s
Current language:  auto; currently minimal
4           strcpy(arr, "1234567");
(gdb) p arr
$1 = "abc\000\000\000\000"
(gdb) c      
Continuing.

Breakpoint 1, a () at str.c:3
3           char arr[8] = "abc";
(gdb) p arr
$2 = "1234567"
(gdb) s
4           strcpy(arr, "1234567");
(gdb) p arr
$3 = "abc\000\000\000\000"
3
  • @Lundin - actually, arr[3] is set to null-termination, so he's right to ask about arr[4] Commented Aug 14, 2012 at 2:38
  • @JamesCaccese Seems to be a typo... anyway, it is all explained in the answer I posted. Commented Aug 14, 2012 at 8:58
  • @Lundin - who's typo, your's or @sidyll's? Your comment above that arr[4] is set to null-termination because of "" is false. arr[3] is set to null-termination because of the "", arr[4] is set to zero because it wasn't initialized explicitly. Your answer below is correct, but your comment is off by one and it confuses the issue. Since you can't edit comments, you should probably remove it. Commented Aug 14, 2012 at 19:06

4 Answers 4

17

It's standard behavior.

arr[3] is initialized to 0 because the terminating 0 is part of the string literal.

All remaining elements are initialized to 0 too -- ISO/IEC 9899:1999, 6.7.8, 21:

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 char objects with static storage are initialized to 0.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the standard reference.
...but that's only defined for a brace-enclosed list, which is not what the code in questioned uses, no?
No, "... or fewer characters in a string literal ...".
8
char arr[8] = "abc";

is completely equivalent to

char arr[8] = {'a', 'b', 'c', '\0'};

ISO C 6.7.8 §21 states that

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.

In plain English this means that all values at the end of your array will be set to 0. So the standard guarantees that your code is equivalent to:

char arr[8] = {'a', 'b', 'c', '\0', 0, 0, 0, 0};

Now of course, '\0' happens to be value zero as well.

This rule is universal to all arrays and not just to strings. Also, the same applies when initializing a struct but only explicitly setting a few of its members (6.7.8 §18).


This is why you can write code like

char arr[8] = "";

In this example, the first element of the array is initialized explicity to '\0', and the rest of the items implicitly to zero. The compiler translates this to

char arr[8] = {0, 0, 0, 0, 0, 0, 0, 0};

2 Comments

What does objects that have static storage duration mean? I cannot understand that part of the specification. Can you please explain it?
@КонстантинВан For posterity: It means global variables or those defined static (both file static or function static). These objects are created before the program starts; the startup code contains commands to "zero out" these objects. This means all pointers are null pointers, all numbers are zero and all character arrays have zero bytes, so that strlen(arr) returns 0. This is actually desirable; the reason this is not done for objects with "automatic storage duration" (local variables) is that it would happen every time the code is passed, as opposed to just once for statics.
3

This is standard behavior. Every element of an array that is not explicitly initialized is initialized to a default value ('\0' for char), if any prefix of the array is initialized in the declaration. It also works for other types:

int a[10] = {1};

zeroes out a[1] through a[9].

Comments

0

According to the standard, all indices beyond what is specified will be set to zero/null. More information in this SO post

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.