使用和不使用优化访问越界索引

时间:2011-12-08 03:24:14

标签: c optimization

当我运行以下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中的指针但是优化如何影响这个呢?

2 个答案:

答案 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>