当我运行以下C代码时,我会得到不同的输出,具体取决于代码是否在打开优化(gcc -O)时运行。
#include <stdio.h>
int main()
{
int b = 55;
int a[2] = {4, 5};
int index;
printf(" index a[index]\n ");
printf("==================\n ");
for(index = 0; index < 6; index++)
{
printf("%2d%12d\n", index, a[index]);
}
return 0;
}
我理解在C中访问索引越界只会从数组中进一步访问堆栈内存(假设为该索引分配了足够的堆栈空间,否则就是segfaults)因为数组只是C中的指针但是优化如何影响这个呢?
答案 0 :(得分:2)
访问越界是未定义的行为。因此,允许编译器执行它想要的任何操作,并允许任何事情发生。因此,试图“猜测”将会发生什么并没有多大意义。
在您的情况下,优化可能会影响数组之外的堆栈的排序和内容。这会给你不同的结果。
答案 1 :(得分:0)
您正在导致未定义的行为,简单明了。你不能真实地说“为什么这种未定义的行为会在这种情况下导致这种结果,但在另一种情况下会产生不同的结果?”
如果要查看哪些指令导致堆栈在优化下不同,请使用 objdump 或 gdb 。
编辑:例如,在使用-O
标志进行编译时,在第一个{{1}之前,main
开头的堆栈存在很多差异为了清楚起见,编译为32位:
未优化:
printf
优化
0x080483c4 <+0>: push ebp
0x080483c5 <+1>: mov ebp,esp
0x080483c7 <+3>: and esp,0xfffffff0
0x080483ca <+6>: sub esp,0x20
0x080483cd <+9>: mov DWORD PTR [esp+0x18],0x37
0x080483d5 <+17>: mov DWORD PTR [esp+0x10],0x4
0x080483dd <+25>: mov DWORD PTR [esp+0x14],0x5
0x080483e5 <+33>: mov eax,0x8048514
0x080483ea <+38>: mov DWORD PTR [esp],eax
0x080483ed <+41>: call 0x80482e0 <printf@plt>