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

时间:2010-07-11 13:29:38

标签: c function

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

#include <stdio.h>

void foo(int a)
{
   printf("%p\n", &a);
}

int main(void)
{
   foo(42);
   return 0;
}

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

<foo>:
  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 <printf@plt>
  c9                      leave  
  c3                      ret   

3 个答案:

答案 0 :(得分:18)

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

答案 1 :(得分:9)

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

答案 2 :(得分:1)

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

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