2015-02-06 40 views
4

写在C便携式功能(没有组件),该返回尝试它的堆栈帧便携式函数,返回它的堆栈帧的大小

int stackframe_size() 
{ 

} 

的解决它的大小below - 该函数在使用VS 2010进行编译时返回228个字节。有没有一种方法可以验证其正确性?

int stackframe_size(int run) 
    { 
     int i ; 

     if(!run) 
     { 
      return ((int)(&i) - stackframe_size(++run)); 

     } 
     return (int)(&i); 

    } 

援引为:

int main() 
    { 
     printf("\nSize of stackframe_size() is: %d bytes",stackframe_size(0)) ; 
     return 0; 
    } 
+0

:)我问这个,因为我想检查是否有一个聪明/清洁的方式来做到这一点,而无需添加读取参数地址的本地变量(比如使用递归技术)。 – Electrix 2015-02-06 03:49:15

+0

听起来像是一个很好的技术给我。也许你应该分享这些代码,并解释它的工作原理和结果。 – user3386109 2015-02-06 03:55:20

+2

你不能拥有这样的*便携*功能。一个假想的整体程序优化编译器可能*有时*没有任何堆栈生成代码;人们可以想象一些没有堆栈的C编译器(但是在一些垃圾收集堆中分配所有的调用帧,就像SML/NJ一样)。所以原则上,甚至不需要堆栈。但是我知道没有这种奇怪的C实现没有堆栈! – 2015-02-06 16:54:36

回答

5

没有这样的便携式功能是可能的。

您的尝试可能与您所能得到的尽可能接近,但指针减法具有未定义的行为。更一般地,p1 - p0,其中p0p1是指向不同对象的指针,具有未定义的行为。

除您的代码减去int作为地址转换结果的值之外。直接减去指针更有可能 - 而指针应该是char*unsigned char*。有很多实现,其中int太小而无法容纳转换的指针,有些指针的表示比您想象的更复杂,并且将它们转换为足够大的整数类型不一定会给您带来有意义的结果。

现实世界中的C实现不使用“堆栈”来表示“堆栈帧”被推送和弹出的连续内存区域。 (从先入后出的数据结构来看,必须有一个“堆栈”,但实现“堆栈”的方式完全没有规定)。例如,一些IBM大型机实现为函数分配内存通过类似堆的方式进行调用,以便两个此类调用的局部变量的地址之间没有定义的关系。

你可以在纯C中编写一个函数(没有汇编语言),该函数为特定的实现提供了一个栈帧的大小。但是由于C语言本身没有“栈帧”的概念(标准甚至没有使用“栈”这个词),所以它不能被轻易地完成。

+0

“没有这样的便携式功能是可能的”的荣誉 - C实现甚至不需要有堆栈。 – paxdiablo 2015-04-16 06:59:26

1

我想检查是否有这样做不会增加局部变量

你可以使用&run而不是一个聪明的/干净的方式&i - 这将为您节省一个本地变量。

有没有办法验证它的正确性?

使用调试器!检查堆栈指针寄存器在你关注的位置,观察发生溢出等。