简体   繁体   中英

Undefined behaviour (?) in C with char arrays

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?

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.

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.

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 int s with the very first one initialized with 1 and the rest set to 0 .

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 .

The contents of uninitialized part of array depends on where it's located (ie 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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM