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

Ben*_*eiß 2 c gcc

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

这是简单的代码:

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

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

int main()
{
    printf("%p\n", func());
}
Run Code Online (Sandbox Code Playgroud)

程序的输出是"(零)".

我刚用"gcc sample.c"编译了这个,并用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.
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*ler 5

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