【问题标题】:Is it legal to take the address of a function parameter?获取函数参数的地址是否合法?
【发布时间】:2010-07-11 13:29:37
【问题描述】:

这段代码 sn-p 是否在 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   

【问题讨论】:

    标签: c function


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      是的,这是完全合法的——当然你不会从函数中返回那个地址,因为当foo 返回时,它已经没有意义了。

      【讨论】:

        【解决方案3】:

        这是完全合法的。但是您需要考虑您获得地址的范围和生命周期。

        如果您设法将其从函数中传回,则该地址可能不再指向有效数据。与 C 中的大部分内容一样,这使您能够在脚上开枪。

        【讨论】:

          猜你喜欢
          • 2013-03-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多