都没有提到结构域*总是*初始化为0(即当结构是在栈上)?(Are unmentioned struc

2019-07-20 17:26发布

从实验(在铛和海湾合作委员会,以-02和-O0) 似乎是在下面的代码

typedef struct foo_s { int i; int j; } foo_t;
int main(void) {
    foo_t foo = {.i = 42};
    ...

foo.j是自动为零。

是由C99保证起,或者是一个编译器的具体实现细节?

注:我甚至试着写0xFFs无效栈下方的内存,在此foo是后来给出的地址。

更新:有一对夫妇的评论指出,这仅仅是因为在堆栈下面内存恰好包含零。 下面的代码是为了确保这不是这种情况,并且可以证明GCC -O0被归零内存。

-7和-6的偏移是编译器依赖性。 他们需要在不同锵。

typedef struct foo_s { int i; int j; } foo_t;

int main(void) {
    int r;
    int *badstack0 = &r - 7;
    int *badstack1 = &r - 6;

    *badstack0 = 0xFF; // write to invalid ram, below stack
    printf("badstack0 %p, val: %2X\n", badstack0, *badstack0);
    *badstack1 = 0xEE; // write to invalid ram, below stack
    printf("badstack1 %p, val: %2X\n", badstack1, *badstack1);

    // struct test
    foo_t foo = {.i = 42};
    printf("&foo.i %p\n", &foo.i);
    printf("&foo.j %p\n", &foo.j);
    printf("struct test: i:%i j:%i\n", foo.i, foo.j);
    return 0;
}

输出:

badstack0 0x7fff221e2e80, val: FF
badstack1 0x7fff221e2e84, val: EE
&foo.i 0x7fff221e2e80
&foo.j 0x7fff221e2e84
struct test: i:42 j:0

Answer 1:

如果你提供任何initialisers,没有明确提及的成员,就好像它们是静态初始化。 这是在6.7.9(19)标准保证:

初始化应初始化列表顺序,提供了一种用于特定子对象重写为同一子对象任何前面列出的初始化每个初始化发生; 未明确初始化所有子对象应被隐式初始化一样具有静态存储持续时间的对象

(由我强调)

如果你不初始化任何成员,所有成员的值是不确定的。



Answer 2:

Ç保证数组/结构/联合为只要至少一个成员*是explictily初始化,然后所有其他成员将被横竖静态存储时间初始化,如丹尼尔·费舍尔的回答引用。 换句话说,所有其他成员被自动设置为零或NULL。

阵列/结构/联合事项的存储类型不是,它们按照同样的规则初始化不管他们是否有自动或静态存储持续时间。

这是不是唯一的东西C99或更高版本,C 一直有此要求。 所有标准的C编译器遵循这个规律,它是规范 ,而不是实现定义。

这有没有关系“调试版本”零个超时。

作为事实上,这条规则就是为什么你可以通过写零的整个阵列的解释

int array[100] = {0}

该代码表示​​,“第一个元素初始化为零,并且如果他们有静态存储时间初始化剩余的99倍的,即让他们也为零”。


(*)这三种类型在C标准正式命名为“聚合型”。



文章来源: Are unmentioned struct fields *always* initialised to zero (i.e. when the struct is on the stack)?