正在未尽结构字段*总是*初始化为0(即当结构是在栈上)? [英] Are unmentioned struct fields *always* initialised to zero (i.e. when the struct is on the stack)?

查看:178
本文介绍了正在未尽结构字段*总是*初始化为0(即当结构是在栈上)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从实验(在铛和海湾合作委员会,与-O2和-O0)是的看起来的在以下code

  typedef结构foo_s {INT I;诠释J; } 脚丫子;
诠释主要(无效){
    foo_t富= {.I = 42};
    ...

foo.j自动为零。

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

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

更新:有一对夫妇的评论指出,这是仅仅因为在堆栈下面内存恰好包含零。下面code可以确保这一点并非如此,而且可能证明GCC -O0是零内存。

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

  typedef结构foo_s {INT I;诠释J; } 脚丫子;诠释主要(无效){
    INT R;
    为int * badstack0 =安培; R - 7;
    为int * badstack1 =安培; R - 6;    * badstack0 = 0xFF的; //写无效RAM,下面堆
    的printf(badstack0%P,VAL:%2X \\ n,badstack0,* badstack0);
    * badstack1 = 0xEE; //写无效RAM,下面堆
    的printf(badstack1%P,VAL:%2X \\ n,badstack1,* badstack1);    //结构测试
    foo_t富= {.I = 42};
    的printf(&安培; foo.i%P \\ N,&安培; foo.i);
    的printf(&安培; foo.j%P \\ N,&安培; foo.j);
    的printf(结构测试:I:%I J:%I \\ N,foo.i,foo.j);
    返回0;
}

输出:

  badstack0 0x7fff221e2e80,VAL:FF
badstack1 0x7fff221e2e84,VAL:EE
&安培; foo.i 0x7fff221e2e80
&安培; foo.j 0x7fff221e2e84
结构测试:I:42 Y:0


解决方案

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


  

初​​始化应发生在初始化列表中的顺序,提供了一个特定的子对象覆盖pviously上市初始化为相同的子对象的任何$ P $每次初始化; 未明确初始化应隐式初始化一样具有静态存储持续时间对象的所有子对象


(由我强调)

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

From experimentation (in Clang and GCC, with -O2 and -O0) is seems that in the following code

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

foo.j is automatically zero.

Is the guaranteed by C99 onwards, or is it a compiler specific implementation detail?

Note: I've even tried writing 0xFFs to invalid memory below the stack, at the address which foo is later given.

Update: There are a couple of comments stating that this is just because the memory below the stack happens to contain zeros. The following code makes sure this is not the case, and may prove that GCC -O0 is zeroing memory.

The offsets of -7 and -6 are compiler dependent. They needed to be different in Clang.

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;
}

Output:

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

解决方案

If you provide any initialisers, the members not explicitly mentioned are initialised as if they were static. That's guaranteed by the standard in 6.7.9 (19):

The initialization shall occur in initializer list order, each initializer provided for a particular subobject overriding any previously listed initializer for the same subobject; all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.

(Emphasis added by me)

If you don't initialise any member, the values of all members are indeterminate.

这篇关于正在未尽结构字段*总是*初始化为0(即当结构是在栈上)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆