获取函数参数的地址是否合法?

这个代码片段是否在ANSI C中定义良好? 在我的系统(Linux x86_64)上,它似乎运行得很好并打印一个地址,但总是这样吗? 例如,参数可能通过寄存器传递,并且获取该地址似乎不正确。

#include  void foo(int a) { printf("%p\n", &a); } int main(void) { foo(42); return 0; } 

编辑:看起来GCC会在获取地址之前将寄存器传递的值放入堆栈。

 : 55 push rbp 48 89 e5 mov rbp,rsp 48 83 ec 10 sub rsp,0x10 89 7d fc mov DWORD PTR [rbp-0x4],edi b8 1c 06 40 00 mov eax,0x40061c 48 8d 55 fc lea rdx,[rbp-0x4] 48 89 d6 mov rsi,rdx 48 89 c7 mov rdi,rax b8 00 00 00 00 mov eax,0x0 e8 d8 fe ff ff call 4003c0  c9 leave c3 ret 

是的,这是完全合法的 – 当然你不会从函数返回该地址,因为当foo返回时,它是没有意义的。

解决您的困惑:是的,参数可能由寄存器传递 ,但当它成为被调用函数中的局部变量时,它就像任何其他局部变量一样。 如果使用和使用它的地址,编译器必须确保它有一个真实的地址,通过它可以通过创建一个真正的堆栈变量来访问它。 如果没有,编译器可能能够优化以将其保存在寄存器中而无需在存储器中实例化它。

这完全合法。 但是你需要考虑你得到的地址的范围和寿命。

如果您设法将其从函数中传回,则该地址可能不再指向有效数据。 就像在C的大部分时间一样,这使你有能力用脚射击自己。