通过实验(在 Clang 和 GCC 中,使用 -O2 和 -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 的偏移量取决于编译器。他们需要在 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;
}
输出:
badstack0 0x7fff221e2e80, val: FF
badstack1 0x7fff221e2e84, val: EE
&foo.i 0x7fff221e2e80
&foo.j 0x7fff221e2e84
struct test: i:42 j:0