即使没有优化,内存中变量的排序通常也不是您可以指望的。无论如何,它们最终的顺序取决于你如何看待它们。如果你看到一群人从最短到最高排列,他人可能会说这些人实际上是从最高到最短。
影响这些变量在内存中的顺序的第一件事就是编译器如何实现。它有一个列表,列表可以从头到尾或从头到尾进行处理。所以编译器读取你的代码,产生中间代码,这个中间代码有一个需要放在堆栈上的局部变量列表。编译器并不关心它们在代码中的顺序,所以它只是以最方便的顺序查看它们。
第二件事是许多处理器使用一个颠倒的堆栈。如果你:
push A
push B
然后A有一个比B更大的地址,尽管B位于堆栈的顶部(并在A之上)。想象这样的一个好方法是使用C数组:
int stk[BIG];
int stk_top = BIG;
然后
void stk_push(int x) {
stk_top--;
stk[stk_top] = x;
}
正如你可以看到stk_top指数实际上缩小为堆栈得到它更多的项目。
现在回到优化 - 编译器在重新排序不在结构中的事物时非常自由。这意味着你的编译器可以很好地对堆栈中的局部变量进行重新排序,并且在那里添加额外的填充字节来保持对齐。另外,编译器也可以自由地将一些局部变量放在堆栈中。仅仅因为你命名了一个局部变量并不意味着编译器必须在程序中真正生成它。如果一个变量没有被实际使用,它可能会被排除在程序之外。如果一个变量被大量使用,它可能被保存在一个寄存器中。如果一个变量只用于程序的一部分,那么它可能只是临时存在,并且它所使用的内存可以在该函数期间在几个其他临时变量之间共享。
@abelenky:哎呀...谢谢你注意到:)修正了它。 – Legend 2010-10-20 16:05:38
请记住,如果编译器发现它们是有益的,那么它们甚至可能不会被放置在堆栈上,它们中的一些可能被存储在寄存器中整个生命周期中。 – nos 2010-10-20 16:14:08
限制变量内存布局,你应该把它们打包在一个'结构'中。在你的例子中,编译器只是按照声明的顺序将它们放到堆栈上,而堆栈则按照相反的顺序被使用。 – valdo 2010-10-20 16:30:43