根据当前的C标准,指定给已声明但未定义的“int”的默认值是什么? C标准问题
简单的问题,但似乎无法用duckduckgo或通过搜索(此处)找到答案 我知道在C语言中,标准规定未初始化的根据当前的C标准,指定给已声明但未定义的“int”的默认值是什么? C标准问题,c,assembly,standards,C,Assembly,Standards,简单的问题,但似乎无法用duckduckgo或通过搜索(此处)找到答案 我知道在C语言中,标准规定未初始化的ints数组会导致未定义的行为。(或者至少大多数编译器都是这样操作的。) 但是,单个int的默认值是什么 INTA; printf(“a=%d”,a) 我的猜测是,由于这是在堆栈上,CPU必须执行一条“推堆栈”指令,该指令必须取一个值,如果没有指定值,编译器使用的最合理的值将是零 我说得对吗 示例测试程序和反汇编 这似乎是有道理的 a: .zero 4 这是否意味着a在.data
int
s数组会导致未定义的行为。(或者至少大多数编译器都是这样操作的。)
但是,单个int
的默认值是什么
INTA;
printf(“a=%d”,a)
我的猜测是,由于这是在堆栈上,CPU必须执行一条“推堆栈”指令,该指令必须取一个值,如果没有指定值,编译器使用的最合理的值将是零
我说得对吗
示例测试程序和反汇编
这似乎是有道理的
a:
.zero 4
这是否意味着a在.data
部分被初始化为4x0x00
(字节)?在您的示例中
#include <stdio.h>
int a;
int main(void)
{
printf("%d\n", a);
return 0;
}
它有一个不确定的值,使用该值将调用未定义的行为
引用6.7.9.10:
如果没有显式初始化具有自动存储持续时间的对象,则其值为不确定的如果具有静态或线程存储持续时间的对象未初始化
那么明确地说:
-如果有指针类型,则初始化为空指针
-如果它有算术类型,则初始化为(正或无符号)零
-如果是聚合,则根据这些规则(递归地)初始化每个成员,
并且任何填充被初始化为零位
-如果它是一个联合,则第一个命名成员将根据以下内容(递归地)初始化
规则,并且任何填充都初始化为零位
自动变量和动态变量没有默认值。对于静态变量,默认值是0,但IIRC它以前也是未定义的。我听说使用未初始化数组的值不会调用未定义的行为,因为数组不能用
寄存器声明。Re“我的猜测是,由于这是在堆栈上,CPU必须执行一条“推堆栈”指令”:不,可以通过调整堆栈指针和一条加法或减法指令来保留堆栈上的空间。通常,在某些体系结构中,例程开始时的代码对堆栈指针进行一次调整,以便为例程在堆栈上使用的所有数据腾出空间。它们通常进入一个名为.bss
的区域,而不是.data
。一些系统名称为.bss
作为.data
的一部分。在这个上下文中,“线程存储持续时间”大概是指“全局变量”?@FreedoleConsultant:不,全局变量有“静态存储持续时间”,与文件范围静态int foo
变量相同。“线程存储持续时间”是线程本地存储,其中每个线程都可以看到全局作用域或文件作用域变量的不同副本。不要被以下事实所愚弄:static
关键字只是静态(在编译时分配)存储的一种情况。好的,谢谢你澄清这一切都是错误的,或者至少是不准确的。首先,它是UB,因为自动存储变量没有地址。其次,读取一个不确定的值会在大多数系统上调用未指定的行为,除非存在陷阱表示,这在int
中很少出现。请参阅我的回答。@Lundin对上述问题中的disassembly有何评论?
.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
#include <stdio.h>
int a;
int main(void)
{
printf("%d\n", a);
return 0;
}
#include <stdio.h>
int main(void)
{
int a;
printf("%d\n", a);
return 0;
}