临时变量在stcak中顺序(gcc4.4)

来源:互联网 发布:moto360怎么同步软件 编辑:程序博客网 时间:2024/06/04 01:34

 

朋友问我一道题他碰到的笔试题:

 

sizeof(b)求b所占用的空间,这个是3没有问题。

 

strlen仅仅根据'/0'的出现判断字符串大小,而不管'/0'是不是出现在数组之内。由于b的末尾没有'/0',所以strlen(b)的值依赖于程序的内存布局。

 

我记得李先静兄在《系统程序员成长计划》里提到过gcc对临时变量的进栈顺序处理,查了一下:
“gcc不同版本的处理是不一样的,对于老版本的gcc(如gcc3.4),第一个临时变量放在最高的地址,第二个其次,依次顺序分布。而对于新版本的gcc(如gcc4.3),临时变量的位置是反的,即最后一个临时变量在最高的地址,倒数第二个其次,依次顺序分布。”

 

不管是临时变量在栈中的顺序是递增还是递减,只要是有序的,那么strlen(b)的值就应该是6,我估计这也是出题者在b的前后各放了一个4字节长的数组的原因。

 

朋友验证之后告诉我,他在gcc4.4.1下输出是7 3,于是我做了下面的实验,验证临时变量在stack中的排列顺序:

 

Unbuntu + gcc 4.4.1

输出:
bffff448 bffff444 bffff44d bffff440
7 3
从内存布局可以看出,gcc调整了变量的顺序,难道是为了32bit对齐所作的优化?

 

接着来,多定义了一个char变量:

输出:
bffff448 bffff444 bffff44c bffff440
3 3
果然是把新定义的char变量放到了b的后面,这些不对齐的变量放到了堆栈的高地址(先入栈)。

 

接着验证:

输出:
bffff44c bffff448 bffff444 bffff440
7 4
b也是32bit对齐后,变成了先定义的在堆栈高地址(先声明先入栈)。

 

再来: 

 

输出:
bffff448 bffff444 bffff440 bffff43c
7 4
再次加入char 类型变量之后,不是32bit对齐的char放在了堆栈的高地址处。

 

windows下用 codeblock + mingw(gcc 4.4.4)测试了一下题目的代码:

堆栈里的数据如下:

gcc4.4.4没有优化32bit对齐,先声明先入栈。

 

结论:

临时变量在栈中的顺序没有强制规定,完全依赖于编译器的实现,不应该对它做任何假设。

 

题外话:

这些没有标准可查、像期末考试题一样的笔试题不知道什么时候才能消失。