【问题标题】:How to write a function which return a pointer to the stack如何编写一个返回指向堆栈的指针的函数
【发布时间】:2016-04-07 09:42:05
【问题描述】:

在阅读了以下question 之后,我了解到不存在这样的东西(至少不是'便携式')。

但是,我正在关注来自 mono 代码库的以下 piece of code,它返回一个指向堆栈的指针:

static void *
return_stack_ptr ()
{
    gpointer i;
    return &i;
}

我很惊讶上面的代码甚至可以在诸如 PowerPC 之类的 Arch 上运行,我原以为这只适用于 x86(也许只有 gcc)。

这可以在 PowerPC 上运行吗?

【问题讨论】:

  • 在 C 中没有可以返回指向堆栈指针的可移植函数。只有一定程度的不可移植性。
  • 这种东西是平台和编译器相关的。
  • PowerPC ABI 确实有堆栈内存的概念,但是您的编译器可能会选择将变量i 放在堆栈以外的另一个内存中。不过,我会说它适用于任何主流 PowerPC 编译器
  • @atturri:如果您(正确地)使用它的地址,编译器必须将变量i 放在内存中的某个位置。别无选择。
  • @atturri:无论如何,“堆栈”是一个非正式术语,用于“存储局部变量的内存区域”。根据定义,&i 指向堆栈内部。但是,不能保证“堆栈”是一个连续的内存区域,或者&i 位于任一端,或者您可以对&i 进行指针运算。

标签: c x86 powerpc stack-frame


【解决方案1】:

堆栈的目的是支持函数调用和局部变量。如果您的系统有一个堆栈,它将使用它,并在那里分配局部变量。所以假设局部变量的地址指向堆栈中的某个地方是非常合理的。这不是特定于 x86 或 gcc - 这是一个相当普遍的想法。

但是,使用指向不存在的变量的指针(即超出范围后)是未定义行为。所以这个函数不能保证做任何有意义的事情。事实上,“聪明”的编译器可以检测到您的程序使用了未定义的行为,并用无操作替换您的代码(并称其为“性能优化”)。

或者,“明智的”编译器可以识别出您的函数返回一个指向堆栈的指针,并通过使用硬件堆栈指针来内联它。

这两个选项都不能保证 - 此代码不可移植。

【讨论】:

  • 请注意,拥有一个曾经有效的指针的行为本身并不是UB。例如,这只是free(ptr) 返回后的正常状态。
猜你喜欢
  • 1970-01-01
  • 2014-08-18
  • 2020-01-03
  • 2016-11-09
  • 2011-01-12
  • 2013-04-10
  • 2021-06-25
  • 2016-08-08
  • 1970-01-01
相关资源
最近更新 更多