这是可以接受的,因为整数的大小(以字节为单位)在编译期间是已知的,因此编译器知道整个列表需要多少空间。
但要理解这个答案,必须深入挖掘并询问为什么在编译期间知道确切的大小如此重要。一般而言:为您的程序定义virtual address space。
其中一部分是存储局部变量的堆栈,并且不能与堆内存(malloc 工作的地方)混淆。堆栈是一个后进先出列表,还包含所有函数调用及其参数。它用于函数的末尾跳回,您来自哪里,并为此存储了一个内存地址。当你在你的函数中时,你放在堆栈上的所有东西都必须被释放,以便获得正确的跳转地址并避免潜在的段错误。
幸运的是,C 会自动为我们进行这种类型的内存管理,并在我们认为“超出范围”时释放我们所有的 automatic variables。为此,我们需要我们压入堆栈的确切大小,这就是编译器需要知道该大小的原因。
要说明编译器如何翻译您的代码并对这些数字进行硬编码,请参见此处:
$ echo "int int_size = sizeof(int); int main(void) { int arr[] = {10, 20, 30, 40, 50}; }" |\
gcc -c -xc -S -o- -masm=intel -
.file ""
.intel_syntax noprefix
.text
.globl main
.type main, @function
# [...] removed int_size here to keep it shorter. its "4" ;)
main:
.LFB0:
.cfi_startproc
push rbp # < backup rbp / stack base pointer
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
mov rbp, rsp # < rsp / stack shift pointer = top of the stack
.cfi_def_cfa_register 6
sub rsp, 32
mov rax, QWORD PTR fs:40
mov QWORD PTR -8[rbp], rax
xor eax, eax
mov DWORD PTR -32[rbp], 10 # < 10 is one element from the array
mov DWORD PTR -28[rbp], 20 # < -28 means relative to the top of the stack
mov DWORD PTR -24[rbp], 30
mov DWORD PTR -20[rbp], 40
mov DWORD PTR -16[rbp], 50
mov eax, 0
mov rdx, QWORD PTR -8[rbp]
xor rdx, QWORD PTR fs:40
je .L3
call __stack_chk_fail@PLT
.L3:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 8.2.1 20181127"
.section .note.GNU-stack,"",@progbits