C 代码与阴影结构声明的混淆行为
Confusing behavior of C code with shadowed struct declaration
考虑以下 C 代码:
#include <stdio.h>
typedef struct {
int a;
} TestType;
int main(){
int an_int;
TestType test;
// printf("%d\n",test.a);
{
TestType test;
test.a = 777;
printf("offset: %lld\n", &test.a - &an_int); // maybe 2?
}
printf("%d\n", test.a); // should be garbage
printf("offset: %lld\n", &test.a - &an_int); // maybe 1?
}
我声明一个 TestType test
,然后启动一个作用域并声明另一个 TestType test
覆盖第一个。最后 print 语句的预期输出是堆栈中的任何内容。使用 gcc -o stack-allocate-weird stack-allocate-weird.c
和 运行 编译,我得到输出:
offset: 1
777
offset: 1
所以这两个位置是一样的。此外,valgrind ./stack-allocate-weird
没有报告任何错误。取消注释第一个打印语句会得到预期的输出:
-771776240
offset: 2
-771776240
offset: 1
如果我只是声明一个 int
而不是 struct TestType
,代码将按预期运行(最后一个 print 语句打印垃圾)。
我把代码放到服务器上编译得到:
offset: -2
0
offset: -1
哪个看起来也不错(我猜堆栈的方向相反?)。另一方面,将在我的计算机上编译的二进制文件移至服务器给出了原始的错误输出:
offset: 1
777
offset: 1
这是 gcc 的已知错误吗?
gcc -v
在我的电脑上说(一堆其他的东西和):
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04)
在服务器上显示:
gcc version 8.3.1 20190223 (Red Hat 8.3.1-2) (GCC)
所以也许这在两者之间的某个地方得到了修复?
我认为这不是 GCC 的错误。编译器正在延迟外部 TestType test
的分配,直到需要它为止。这是第 16 行中的第二个 printf()
。内部 TestType test
位于偏移量 1,就像您看到的那样,直到它的范围关闭并且它的内存再次空闲。现在需要外部的并且采用完全相同的 space,为您提供内部的值和相同的偏移量。
考虑以下 C 代码:
#include <stdio.h>
typedef struct {
int a;
} TestType;
int main(){
int an_int;
TestType test;
// printf("%d\n",test.a);
{
TestType test;
test.a = 777;
printf("offset: %lld\n", &test.a - &an_int); // maybe 2?
}
printf("%d\n", test.a); // should be garbage
printf("offset: %lld\n", &test.a - &an_int); // maybe 1?
}
我声明一个 TestType test
,然后启动一个作用域并声明另一个 TestType test
覆盖第一个。最后 print 语句的预期输出是堆栈中的任何内容。使用 gcc -o stack-allocate-weird stack-allocate-weird.c
和 运行 编译,我得到输出:
offset: 1
777
offset: 1
所以这两个位置是一样的。此外,valgrind ./stack-allocate-weird
没有报告任何错误。取消注释第一个打印语句会得到预期的输出:
-771776240
offset: 2
-771776240
offset: 1
如果我只是声明一个 int
而不是 struct TestType
,代码将按预期运行(最后一个 print 语句打印垃圾)。
我把代码放到服务器上编译得到:
offset: -2
0
offset: -1
哪个看起来也不错(我猜堆栈的方向相反?)。另一方面,将在我的计算机上编译的二进制文件移至服务器给出了原始的错误输出:
offset: 1
777
offset: 1
这是 gcc 的已知错误吗?
gcc -v
在我的电脑上说(一堆其他的东西和):
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04)
在服务器上显示:
gcc version 8.3.1 20190223 (Red Hat 8.3.1-2) (GCC)
所以也许这在两者之间的某个地方得到了修复?
我认为这不是 GCC 的错误。编译器正在延迟外部 TestType test
的分配,直到需要它为止。这是第 16 行中的第二个 printf()
。内部 TestType test
位于偏移量 1,就像您看到的那样,直到它的范围关闭并且它的内存再次空闲。现在需要外部的并且采用完全相同的 space,为您提供内部的值和相同的偏移量。