C - GCC在返回本地堆栈地址时生成错误的指令

时间:2016-05-01 14:37:19

标签: c gcc

当我编写一个函数时,GCC会生成错误的指令 返回对局部变量的引用。我完全知道你不应该这样做。

这是简单的代码:

#include <stdio.h>
#include <stdlib.h>

int *func()
{
    int a = 100;
    return &a;
}

int main()
{
    printf("%p\n", func());
}

该计划的输出是&#34;(无)&#34;。

我刚用&#34; gcc sample.c&#34;编译了这个。并用gdb:

反汇编可执行文件
Dump of assembler code for function func:
   0x00000000004004e6 <+0>: push   %rbp
   0x00000000004004e7 <+1>: mov    %rsp,%rbp
   0x00000000004004ea <+4>: movl   $0x64,-0x4(%rbp)
   0x00000000004004f1 <+11>:    mov    $0x0,%eax
   0x00000000004004f6 <+16>:    pop    %rbp
   0x00000000004004f7 <+17>:    retq   
End of assembler dump.
Dump of assembler code for function main:
   0x00000000004004f8 <+0>: push   %rbp
   0x00000000004004f9 <+1>: mov    %rsp,%rbp
   0x00000000004004fc <+4>: mov    $0x0,%eax
   0x0000000000400501 <+9>: callq  0x4004e6 <func>
   0x0000000000400506 <+14>:    mov    %rax,%rsi
   0x0000000000400509 <+17>:    mov    $0x4005a4,%edi
   0x000000000040050e <+22>:    mov    $0x0,%eax
   0x0000000000400513 <+27>:    callq  0x4003c0 <printf@plt>
   0x0000000000400518 <+32>:    mov    $0x0,%eax
   0x000000000040051d <+37>:    pop    %rbp
   0x000000000040051e <+38>:    retq   
End of assembler dump.

如您所见,返回值为 0 。它应该是-0x4(%rbp)。 我没有发现任何解释。我的猜测是GCC开发人员希望这段代码尽快失败(空指针解除引用),但这不可能。编译器必须生成正确的指令。 我用GCC 5.3.0对此进行了测试。

1 个答案:

答案 0 :(得分:5)

编译器已生成正确的指令。您正在做的事情不是由C标准定义的,因此编译器可以随意做任何事情。在这种情况下,似乎GCC喜欢返回一个空指针,可能是因为你的程序会尽快失败。