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.
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.
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.
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