4

用 C 编写一个可移植函数(无需汇编),返回其堆栈帧的大小

int stackframe_size()
{

}

尝试如下解决 - 使用 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;
    }
4

2 回答 2

5

不可能有这样的便携功能。

您的尝试可能尽可能接近,但指针减法具有未定义的行为。更一般地说,p1 - p0wherep0p1are 指向不同对象的指针具有未定义的行为。

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

现实世界的 C 实现不使用“堆栈”,即在其上推送和弹出“堆栈帧”的连续内存区域。(在先进后出数据结构的意义上,必须有一个“堆栈”,但完全未指定“堆栈”的实现方式。)例如,一些 IBM 大型机实现为函数分配内存通过堆之类的东西调用,因此两个这样的调用的局部变量的地址之间没有定义的关系。

您可能可以用纯 C(不使用汇编语言)编写一个函数,为您提供特定实现的堆栈帧大小。但是由于 C 语言本身没有“栈帧”的概念(标准甚至没有使用“栈”这个词),所以不能移植。

于 2015-02-06T18:41:02.937 回答
1

我想检查是否有一种聪明/更清洁的方法可以在不添加局部变量的情况下做到这一点

您可以使用&run而不是&i- 这将为您节省一个局部变量。

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

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

于 2015-02-06T18:34:35.667 回答