Declared objects of static duration (those declared outside a function, or with a static
qualifier) which have no specified initializer are initialized to whatever value would be represented by a literal zero [i.e. an integer zero, floating-point zero, or null pointer, as appropriate, or a structure or union containing such values]. If the declaration of any object (including those of automatic duration) includes an initializer, portions whose values are specified by that initializer will be set as specified, and the remainder will be zeroed as with static objects.
For automatic objects without initializers, the situation is somewhat more ambiguous. Given something like:
#include <string.h>
unsigned char static1[5], static2[5];
void test(void)
{
unsigned char temp[5];
strcpy(temp, "Hey");
memcpy(static1, temp, 5);
memcpy(static2, temp, 5);
}
the Standard is clear that test
would not invoke Undefined Behavior, even though it copies portions of temp
that were not initialized. The text of the Standard, at least as of C11, is unclear as to whether anything is guaranteed about the values of static1[4]
and static2[4]
, most notably whether they might be left holding different values. A defect report states that the Standard was not intended to forbid a compiler from behaving as though the code had been:
unsigned char static1[5]={1,1,1,1,1}, static2[5]={2,2,2,2,2};
void test(void)
{
unsigned char temp[4];
strcpy(temp, "Hey");
memcpy(static1, temp, 4);
memcpy(static2, temp, 4);
}
which could leave static1[4]
and static2[4]
holding different values. The Standard is silent on whether quality compilers intended for various purposes should behave in that function. The Standard also offers no guidance as to how the function should be written if the intention if the programmer requires that static1[4]
and static2[4]
hold the same value, but doesn't care what that value is.