Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are unmentioned struct fields *always* initialised to zero (i.e. when the struct is on the stack)?

From experimentation (in Clang and GCC, with -O2 and -O0) is seems that in the following code

typedef struct foo_s { int i; int j; } foo_t;
int main(void) {
    foo_t foo = {.i = 42};
    ...

foo.j is automatically zero.

Is the guaranteed by C99 onwards, or is it a compiler specific implementation detail?

Note: I've even tried writing 0xFFs to invalid memory below the stack, at the address which foo is later given.

Update: There are a couple of comments stating that this is just because the memory below the stack happens to contain zeros. The following code makes sure this is not the case, and may prove that GCC -O0 is zeroing memory.

The offsets of -7 and -6 are compiler dependent. They needed to be different in Clang.

typedef struct foo_s { int i; int j; } foo_t;

int main(void) {
    int r;
    int *badstack0 = &r - 7;
    int *badstack1 = &r - 6;

    *badstack0 = 0xFF; // write to invalid ram, below stack
    printf("badstack0 %p, val: %2X\n", badstack0, *badstack0);
    *badstack1 = 0xEE; // write to invalid ram, below stack
    printf("badstack1 %p, val: %2X\n", badstack1, *badstack1);

    // struct test
    foo_t foo = {.i = 42};
    printf("&foo.i %p\n", &foo.i);
    printf("&foo.j %p\n", &foo.j);
    printf("struct test: i:%i j:%i\n", foo.i, foo.j);
    return 0;
}

Output:

badstack0 0x7fff221e2e80, val: FF
badstack1 0x7fff221e2e84, val: EE
&foo.i 0x7fff221e2e80
&foo.j 0x7fff221e2e84
struct test: i:42 j:0
like image 653
fadedbee Avatar asked Dec 11 '22 17:12

fadedbee


1 Answers

If you provide any initialisers, the members not explicitly mentioned are initialised as if they were static. That's guaranteed by the standard in 6.7.9 (19):

The initialization shall occur in initializer list order, each initializer provided for a particular subobject overriding any previously listed initializer for the same subobject; all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.

(Emphasis added by me)

If you don't initialise any member, the values of all members are indeterminate.

like image 115
Daniel Fischer Avatar answered May 16 '23 02:05

Daniel Fischer