gpt4 book ai didi

c - 为什么 gcc 返回 0 而不是堆栈分配变量的地址?

转载 作者:太空狗 更新时间:2023-10-29 15:03:34 25 4
gpt4 key购买 nike

作为使用自定义堆栈的实验的一部分,我想要一个函数来返回堆栈分配的 char 缓冲区的地址。

// return pointer to stack variable
void *foo(void)
{
char sz[10] = "hello";
return sz;
}

我知道在 C 中这样做是非法的,gcc 也发出警告。

gcc -Wall -Wextra -pedantic -std=gnu99 -fomit-frame-pointer -O0 -c foo.c 

foo.c:8:12: warning: function returns address of local variable [-Wreturn-local-addr]
return sz;

不过,由于这是实验的一部分,我希望代码保持原样。有趣的是生成的代码返回的不是sz的栈地址而是0:

boa@localhost:~/tmp$ objdump -dMintel foo.o
0000000000000000 <foo>:
0: 48 b8 68 65 6c 6c 6f movabs rax,0x6f6c6c6568
7: 00 00 00
a: 48 89 44 24 f0 mov QWORD PTR [rsp-0x10],rax
f: 66 c7 44 24 f8 00 00 mov WORD PTR [rsp-0x8],0x0
16: b8 00 00 00 00 mov eax,0x0
1b: c3 ret

如你所见,0x0 被移动到 eax,这让我感到困惑。为什么 gcc 这样做?

这是一个完整的源文件,其中包含另一个函数 bar() 以及一个主函数。 bar() 按预期返回地址。

#include <stdint.h>
#include <stdio.h>

// return pointer to stack variable
void *foo(void)
{
char sz[10] = "hello";
return sz;
}

void *bar(void)
{
char sz[10] = "hello";
intptr_t i = (intptr_t)sz;
return (void*)i;
}

int main(void)
{
printf("foo: %p\n", foo());
printf("bar: %p\n", bar());
return 0;
}

boa@localhost:~/tmp$ make foo && ./foo
cc foo.o -o foo
foo: (nil)
bar: 0x7ffce518a268

这对我来说是个谜。 gcc 选择背后的逻辑可能是什么?

最佳答案

在这种情况下,GCC 故意返回 NULL,从 code 可以看出:

tree zero = build_zero_cst (TREE_TYPE (val));
gimple_return_set_retval (return_stmt, zero);
update_stmt (stmt);

较新版本的 GCC 和 Clang 更积极地利用未定义的行为,因此这种检查并不令人惊讶。它还使代码快速失败,这在大多数情况下是一件好事(显然不是你的)。

关于c - 为什么 gcc 返回 0 而不是堆栈分配变量的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40290049/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com