堆栈上局部变量分配的顺序 [英] Order of local variable allocation on the stack

查看:28
本文介绍了堆栈上局部变量分配的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看看这两个函数:

void function1() {
    int x;
    int y;
    int z;
    int *ret;
}

void function2() {
    char buffer1[4];
    char buffer2[4];
    char buffer3[4];
    int *ret;
}

如果我在 gdb 中的 function1() 处中断,并打印变量的地址,我会得到:

If I break at function1() in gdb, and print the addresses of the variables, I get this:

(gdb) p &x  
$1 = (int *) 0xbffff380
(gdb) p &y
$2 = (int *) 0xbffff384
(gdb) p &z
$3 = (int *) 0xbffff388
(gdb) p &ret
$4 = (int **) 0xbffff38c

如果我在 function2() 做同样的事情,我会得到这个:

If I do the same thing at function2(), I get this:

(gdb) p &buffer1
$1 = (char (*)[4]) 0xbffff388
(gdb) p &buffer2
$2 = (char (*)[4]) 0xbffff384
(gdb) p &buffer3
$3 = (char (*)[4]) 0xbffff380
(gdb) p &ret
$4 = (int **) 0xbffff38c

您会注意到,在这两个函数中,ret 存储在最靠近堆栈顶部的位置.在function1()中,后面是zy,最后是x.在function2()中,ret后面是buffer1,然后是buffer2buffer3.为什么存储顺序会发生变化?我们在这两种情况下都使用相同数量的内存(4 字节 ints 与 4 字节 char 数组),所以这不是填充问题.这种重新排序的原因是什么?此外,是否可以通过查看 C 代码来提前确定局部变量将如何排序?

You'll notice that in both functions, ret is stored closest to the top of the stack. In function1(), it is followed by z, y, and finally x. In function2(), ret is followed by buffer1, then buffer2 and buffer3. Why is the storage order changed? We're using the same amount of memory in both cases (4 byte ints vs 4 byte char arrays), so it can't be an issue of padding. What reasons could there be for this reordering, and furthermore, is it possible by looking at the C code to determine ahead of time how the local variables will be ordered?

现在我知道 C 的 ANSI 规范没有说明局部变量的存储顺序,并且允许编译器选择自己的顺序,但我想编译器有关于它如何存储的规则处理这一点,并解释为什么制定这些规则.

Now I'm aware that the ANSI spec for C says nothing about the order that local variables are stored in and that the compiler is allowed to chose its own order, but I would imagine that the compiler has rules as to how it takes care of this, and explanations as to why those rules were made to be as they are.

作为参考,我在 Mac OS 10.5.7 上使用 GCC 4.0.1

For reference I'm using GCC 4.0.1 on Mac OS 10.5.7

推荐答案

我不知道 为什么 GCC 按照它的方式组织它的堆栈(虽然我猜你可以破解它的源代码或 这篇论文 并找出),但我可以告诉你如何保证特定堆栈变量的顺序,如果出于某种原因,您需要这样做.只需将它们放在一个结构中:

I've no idea why GCC organizes its stack the way it does (though I guess you could crack open its source or this paper and find out), but I can tell you how to guarantee the order of specific stack variables if for some reason you need to. Simply put them in a struct:

void function1() {
    struct {
        int x;
        int y;
        int z;
        int *ret;
    } locals;
}

如果我没记错的话,规范保证 &ret >&z >&y >&x.我把 K&R 留在工作中,所以我不能引用章节和诗句.

If my memory serves me correctly, spec guarantees that &ret > &z > &y > &x. I left my K&R at work so I can't quote chapter and verse though.

这篇关于堆栈上局部变量分配的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆