本帖最后由 kiton_law 于 2010-4-20 23:22 编辑
如下:
struct sta
{
char a;
int b;
};
struct stb
{
char a;
struct sta b;
long long c;
};
在一个32位的C编译器中(比如ARMCC、GCC或WIN32 VC)不使用任何编译器强制对齐参数的情况下(比如align,pack等)sizeof(struct stb)= ?,不要用编译器去试,靠自己的理解回答,答错的都可以去面壁了,虽然是无聊的题,但可以考验你的基本功(此题80%的求职笔试中都有)。
-----2010年4月 添加-----
晕,突然翻到这个帖子,居然有这么多人的回复
首先谢谢43楼panyi1013的回复,你说我的说法在正常的情况下是正确的,可后面有人疑问这个“正常情况”是什么意思
这里我解答一下,我的前面帖子说的其实是一种理想情况,这种理想情况可以理解为panyi1013所说的正常情况,那就是“编译器把所有类型的变量按照他们的自然长度对齐”,当然这个自然长度是递归到变量类型中的最基本的且最长那个类型,比如你定义了一个结构A,它有结构B的子成员,而结构B的没有结构类型的成员,最长成员是long long,如果long long在这里是8字节,那么long long就是A的自然长度了,也就是8字节。
但一般情况下,编译器根据处理器的硬件体系,会选择是否按照所有类型的自然长度去对齐它们自身,比如,某些ARM编译器是把8字节自然长度的类型,拆成4字节自然长度来对齐,因为ARM寄存器就只有4字节长,8字节对齐和4字节对齐对于寄存器操作是一样的。这就是“不正常情况”了,或者叫不理想情况,如果是这种情况,则具体情形取决于编译器。
而我的研究是基于VC .Net 2003,这个编译器兼容64位,所以它不会把long long 这样的类型去做4字节对齐,这样在64位寄存器的处理器下是会产生地址异常的,而是作8字节对齐,而改编译器支持的最长基本类型的自然长度就是8了,这就意味着所有类型的自然长度都不会超过8,因此无法实验16字节长度的变量
所以结论就是,如果编译器考虑64位兼容,则不会把8字节长的基础变量拆成4字节对齐,否则就一般会这么做(除非某些强制要求的场合,比如你规定的或者某些汇编器的堆栈对齐),这也是某些同学在IAR下实验结果和我不同的原因。
这些全说明白了吧,总结如下:
1.在最高支持64位的编译器下(指支持64位寄存器),基础类型自然长度最大是8(long long)
2.在最高支持32位的编译器下,基础类型自然长度最大一般是4(long long有可能被拆到4字节对齐),可能是8
3.一个复杂类型的自然长度等于它所递归包含的最早且最长的基础类型的自然长度
4.数据总是被对齐到它所属类型的自然长度的边界地址(没有pack编译指令的情况下)
5.一个变量的长度总是其类型(不论基础还是复杂)自然长度的整数倍 |