【发布时间】:2021-03-02 11:37:08
【问题描述】:
C标准问题
简单的问题,但似乎无法通过鸭子鸭或搜索 SO(此处)找到答案。
我知道在 C 中,标准规定 ints 的未初始化数组会导致未定义的行为。 (或者至少大多数编译器都是这样的。)
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)
但是,单个int 的默认值是多少?
int a; printf("a=%d", a);
我的猜测是,由于这是在堆栈上,因此 CPU 必须执行“推堆栈”指令,并且该指令必须采用一个值,并且如果没有值,编译器将使用最合理的值被指定为零。
我说的对吗?
示例测试程序和反汇编
#include <stdio.h>
int a;
int main(void)
{
printf("%d\n", a);
return 0;
}
这是反汇编:(`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
这似乎有一行
a:
.zero 4
这是否意味着 a 在 .data 部分中被初始化为一块内存为 4x 0x00(字节)?
【问题讨论】:
-
自动和动态变量没有默认值。对于静态变量,默认值为 0,但 IIRC 过去也未定义。
-
我听说使用未初始化数组的值不会调用未定义的行为,因为数组不能用
register声明。 -
Re“我的猜测是,由于这是在堆栈上,因此必须由CPU执行“推堆栈”指令”:不,可以通过调整堆栈来保留堆栈上的空间指针,带有加法或减法指令。通常,在某些体系结构中,例程开始处的代码会对堆栈指针进行一次调整,以便为例程在堆栈上使用的所有数据腾出空间。
-
通常他们会进入一个名为
.bss而不是.data的区域。有些系统将.bss命名为.data的一部分。