As part of an experiment using custom stacks, I wanted a function to return the address of a stack allocated char buffer.
// return pointer to stack variable
void *foo(void)
{
char sz[10] = "hello";
return sz;
}
I know that it's illegal to do this in C, and gcc warns too.
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;
Still, since this is part of an experiment, I want the code as is. The funny thing is that the generated code returns 0 instead of sz's stack address:
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
As one can see, 0x0 is moved to eax, which is what puzzles me. Why does gcc do this?
Here's a complete source file with another function, bar(), as well as a main function. bar() returns the address as expected.
#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
", foo());
printf("bar: %p
", bar());
return 0;
}
boa@localhost:~/tmp$ make foo && ./foo
cc foo.o -o foo
foo: (nil)
bar: 0x7ffce518a268
This is a mystery to me. What may be the logic behind gcc's choice?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…