c/c++语言开发共享为什么函数调用而不是变量地址用于检测堆栈增长方向?

我读到了检测堆栈增长检测问题的不同响应,我理解,在现代架构中,堆栈可能会随机增长,可能会在堆外创建,依此类推。

但是,在这个经典的访谈问题中,我想了解为什么人们使用函数调用而不是在同一函数中比较2个局部变量。 我认为必须有一些特殊的理由这样做,但不是一个C /低级开发人员[Java :)],我只是在猜测。

这是我试过的代码:

void sub (int *a) { int b; int c; printf ("a:%dn", a); printf ("b:%dn", &b); printf ("c:%dn", &c); if (&b > a) { printf ("Stack grows up.n"); } else { printf ("Stack grows down.n"); } } int main (void) { int a; int b; sub (&a); printf ("nHere we go again!!n"); if (&b > &a) { printf ("Stack grows up.n"); } else { printf ("Stack grows down.n"); } return 0; } 

我还发现这篇文章试图优化我不理解的解决方案: http : //www.devx.com/tips/Tip/37412

PS:从对这个和其他线索的不同反应来看,似乎问题本身是有缺陷/不相关的,作为面试问题它可能会重新执行不正确的假设,除非有人研究答案!

谢谢!

    单个堆栈框架内,编译器可以根据需要自由地对局部变量进行排序,因此代码如下:

     int i; double j; 

    j之前或之后可能有i 。 只要编译生成正确的代码来访问变量,它就可以去任何地方。

    实际上,除非你使用address-of运算符& (或者必须得到地址),否则变量可能永远不会在堆栈上。 它可以在呼叫期间存储在寄存器中。

    但是,堆栈帧本身的放置顺序是受限制的,因为如果它们出现故障,函数返回将无法正常工作(说得温和)。


    当然,我应该提到堆栈增长的方向仅在非常有限的场景中有用。 绝大多数代码都不应该关心它。 如果您对不同的体系结构以及它们如何处理堆栈感兴趣,请参阅此答案 。

    您无法完全控制编译器选择分配局部变量的顺序。但是,您可以合理地控制将要调用的函数以及按什么顺序控制。

    声明变量将放置在堆栈上的顺序是未定义的,但在函数调用的函数中,内部函数调用的参数必然会在外部函数的后面推送到堆栈上。

    编译器可以并且对堆栈帧中的变量进行重新排序:

     #include  int main () { char c1; int a; char c2; int b; printf("%p %p %p %pn", &c1, &a, &c2, &b); return 0; } 

    打印

     0x7ffff62acc1f 0x7ffff62acc18 0x7ffff62acc1e 0x7ffff62acc14 

    这里(在64位Linux上使用gcc 4.4.3)。 c2已移至c1旁边。

    问题是当你这样做时:

     void test(void) { int a; int b; if (&a < &b) ... 

    您得到的结果与堆栈增长方向无关。 您知道堆栈增长方式的唯一方法是创建新框架 。 编译器可以自由地在其认为合适的位置放置bb以下的b 。 不同的编译器可能给出不同的结果。

    但是,如果调用另一个函数,该函数的局部变量必须位于新的堆栈帧中,即从调用者变量的增长方向。

      以上就是c/c++开发分享为什么函数调用而不是变量地址用于检测堆栈增长方向?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/545908.html

      (0)
      上一篇 2021年1月10日
      下一篇 2021年1月10日

      精彩推荐