Easy question, but couldn't seem to find the answer with a duckduckgo or by searching SO (here).
I am aware that in C, the standard states that uninitialized arrays of int
s results in undefined behaviour. (Or at least most compilers behave this way.)
int a[100]; // 100 x 32bits on stack, values are whatever was left over on the stack
printf("a[5]=%d", a[5]); // undefined behaviour, can be any valid `int` value (-2**15 to 2**15 - 1)
However, what is the default value of a single int
?
int a; printf("a=%d", a);
My guess would be that since this is on the stack, a "push stack" instruction has to be executed by the CPU, and this instruction MUST take a value, and the most sensible value for a compiler to use if no value is specified would be zero.
Am I correct?
#include <stdio.h>
int a;
int main(void)
{
printf("%d\n", a);
return 0;
}
And this is this dissassembly: (`gcc -save-temps -Wall test.c -o test)
.file "test.c"
.text
.globl a
.bss
.align 4
.type a, @object
.size a, 4
a:
.zero 4
.section .rodata
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl a(%rip), %eax
movl %eax, %esi
leaq .LC0(%rip), %rdi
movl $0, %eax
call printf@PLT
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 10.2.1-6) 10.2.1 20210110"
.section .note.GNU-stack,"",@progbits
This appears to have the line
a:
.zero 4
does this mean that a is initialized as a block of memory in the .data
section as 4x 0x00
(bytes) ?
In your example
#include <stdio.h>
int a;
int main(void)
{
printf("%d\n", a);
return 0;
}
The variable a
is declared globally, so it is initialized to zero.
On the other hand, if the variable a
is declared locally and non-statically
#include <stdio.h>
int main(void)
{
int a;
printf("%d\n", a);
return 0;
}
It has an indeterminate value and using the value invokes undefined behavior.
Quote from N1570 6.7.9 Initialization 10:
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static or thread storage duration is not initialized
explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules,
and any padding is initialized to zero bits;
— if it is a union, the first named member is initialized (recursively) according to these
rules, and any padding is initialized to zero bits;