views:

131

answers:

7

when i try

    char bla[32] = "foobar";
    int i;
    putchar(bla[i]);

with strlen(bla) < i < 32, bla[i] is always \0. but isn't this in fact undefined behaviour, and should be avoided?

A: 

The contents of uninitialized part of array depends on where it's located (i.e. on which data segment). In case it's on stack, the uninitialized elements are random values. Generally, if it's global-scope array, the initial contents is also undefined. In case it's supplied with static specificator, compiler is initialized its contents with zeroes at program start.

Accessing this uninitialized part is not prohibited and this doesn't assume undefined behaviour, but the result maybe undefined. Even accessing bla[i] if i > sizeof(bla) is not an undefined behavior, since either you'd have random value or segmentation fault exception.

Pmod
so it is just a compiler "feature"?
guest
this is not a compiler feature, but C specification
n-alexander
@n-alexander: could you cite the paragraph in the cstd? i'm currently looking in it, but can't seem to find it..
guest
This is an array declaration so all parts in the specified range are well defined and initialized to `0` if the initializer is shorter than the array.
Jens Gustedt
From the ansi C standard: http://flash-gordon.me.uk/ansi.c.txt If an object that has static storage duration is not initializedexplicitly, it is initialized implicitly as if every member that hasarithmetic type were assigned 0 and every member that has pointer typewere assigned a null pointer constant. If an object that hasautomatic storage duration is not initialized explicitly, its value isindeterminate.
Radoslav Hristov
A: 

The fact that it is undefined behavior means it can do anything. It may do the same anything everytime, but what is done is anyone's guess.

RC
A: 

That's not a compiler 'feature' but a well documented behavior. The C programming language does not guarantee the value of an uninitialized variable. Therefore you are just guessing what i value is and you can easily access memory which does not belong to your process and on Windows platform, for example, this will lead to Access Violation exception. See http://en.wikipedia.org/wiki/Uninitialized_variable for more information.

Radoslav Hristov
+1  A: 

I think this is well defined behavior, actually a feature. As long as you initialize one element in an array or struct all remaining elements that are not explicitly initialized are initialized to 0.

Jens Gustedt
+5  A: 

In section 6.7.8 of the C99 Standard, paragraph 21 states:

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 paragraph 10 states that static arithmetic types (which would include char) are initialized to zero.

Based on that, you should expect the rest of the array to be initialized to zero when using a string literal as the initializer.

tomlogic
great! thanks a lot!
guest
+4  A: 

C89 spec, section 8.7 "Initialization":

If the array has fixed size, the number of initializers may not exceed the number of members of the array; if there are fewer, the trailing members are initialized with 0.

So, in your usage, the trailing characters are initialized with zeros.

bta
The last remark is incorrect. You don't have to add the `\0` explicitly, because it is always an implicit part of any string literal. So, when you initialize a character array with a string literal, that `\0` is also "copied" to the destination array (assuming there's enough room there).
AndreyT
@AndreyT- Good catch (fixed)
bta
+2  A: 

C language follows the all-or-nothing principle when it comes to initialization. The object is either completely uninitialized or completely initialized. The latter means that if you specify fewer initializers than necessary to initialize the entire object, the rest of the object is implicitly zero-initialized for you by the compiler.

This applies to all aggregate types. In your case it just happens to be a character array initialized with a string literal. In this case, for example,

int a[100] = { 1 };

you get an array of 100 ints with the very first one initialized with 1 and the rest set to 0.

AndreyT