Initialization summary of the structure including the pointer of C language.

The content is C99 compliant. It seems that C11 has not changed in particular. I would like to summarize a little about what happens to the initialization of the next structure in the C language specifications.

#include<stdio.h>

struct S
{
    int val;
    void *ptr;
    int val2;
};

int main(int argc, char *argv[])
{
    struct S a_var = {0};
    static struct S s_var;

    //Display of automatic variables
    printf("%d\n%d\n", a_var.val, a_var.val2);
    if (a_var.ptr == NULL)
    {
        //Processing when NULL
    }

    //Display static variables=>Since it has not been initialized.Placed in bss.
    printf("%d\n%d\n", s_var.val, s_var.val2);
    if (s_var.ptr == NULL)
    {
        //Processing when NULL
    }
    return 0;
}

Let's summarize the contents of the following two pages.

[Stack overflow: Structure initialization including pointer variables in C language](https://ja.stackoverflow.com/questions/33824/c%E8%A8%80%E8%AA%9E%E3%81% AE% E3% 83% 9D% E3% 82% A4% E3% 83% B3% E3% 82% BF% E5% A4% 89% E6% 95% B0% E3% 82% 92% E5% 90% AB% E3% 82% 80% E6% A7% 8B% E9% 80% A0% E4% BD% 93% E5% 88% 9D% E6% 9C% 9F% E5% 8C% 96% E3% 81% AB% E3% 81% A4% E3% 81% 84% E3% 81% A6) Stack Overflow: how about .bss section not zero initialized

Arithmetic type: int / long / char etc.

Initialization state auto /Arithmetic type static /Arithmetic type global/Arithmetic type
Not yet Indefinite 0 0
Already Initialization value Initialization value Initialization value
Initialization state auto /Pointer type static /Pointer type global/Pointer type
Not yet Indefinite NULL NULL
Already Initialization value Initialization value Initialization value

When only the first element of an array or structure is explicitly initialized (A method like "struct S v = {0};" in the above source) Other than the first element, it is initialized in the same way as static and global variable uninitialized variables.

So, the code that uses the above structure will have the following values when the initialization is completed.

 a_var.val -> 0
 a_var.ptr -> NULL
 a_var.val2 -> 0

 s_var.val -> 0
 s_var.ptr -> NULL
 s_var.val2 -> 0

If it conforms to the C99 standard properly, NULL means "it matches 0 when converted to a numeric type", so the int type 0 and NULL values in C language must match. (However, on the C language source, the comparison should not be done (it will reduce readability, so please stop it seriously))

This means that people who make their own OS need to take responsibility for filling .bss with zero when making a program loader.

Even if you make a mistake, do not fill it with 1.

[Addition] There was a tsukkomi saying that the compiler should write the code that clears 0 for the variables stored in the stack, so try disassembling with BinaryNinja.

image.png

The one reserved on the stack forgot that the assignment code was generated and initialized like the part in the red frame. It was pointed out, uh! It became.

By the way, see what happens to .bss with objdump.

image.png

Let's take a look at Binary Ninja for the time being. The initialization value of .bss should not be written in the file (.Bss does not have LOAD in section flag, ALLOC only) BinaryNinja interprets it arbitrarily and substitutes zero arbitrarily. image.png

So, well, if you want to say that the loader side is a processing system that conforms to the C language standard, let's fill .bss with zeros.

that's all

Recommended Posts