我正在测试对齐,我确定iOS模拟器有些奇怪。(XCode 4.3.2和XCode 4.5)。
在iOS模拟器上,即使属性((aligned(4)))用于强制4字节边界,结构也会对齐到8字节边界。检查其末尾是否填充 0x00000001 以对齐8字节边界。
如果myStruct变量在全局范围内定义,则模拟器将其与4字节边界对齐,因此它可能与堆栈相关。
模拟器是i386所以它的32位,它必须与4字节边界对齐。那么,原因是什么,为什么它与64位边界对齐?它是一个功能还是一个bug?
(我知道没有必要与模拟器斗争,但它可能导致陷入微妙的问题。)
typedef struct myStruct
{
int a;
int b;
} myStruct;
//} __attribute__ ((aligned (4))) myStruct;
-(void)alignmentTest
{
// Offset 16*n (0x2fdfe2f0)
int __attribute__ ((aligned (16))) force16ByteBoundary = 0x01020304;
// Offset 16*n-4 (0x2fdfe2ec)
int some4Byte = 0x09080706;
// Offset 16*n-12 (0x2fdfe2e4)
myStruct mys;
mys.a = 0xa1b1c1d1;
mys.b = 0xf2e28292;
NSLog(@"&force16ByteBoundary: %p / &some4Byte: %p / &mys: %p",
&force16ByteBoundary, &some4Byte, &mys);
}
(编辑优化已关闭,-O0)
模拟器(iOS 5.1)结果;
(lldb)x`& mys` -fx
0xbfffda60 :0xa1b1c1d1 0xf2e28292 0x00000001 0x09080706
0xbfffda70 :0x01020304
& force16ByteBoundary:0xbfffda70 /& some4Byte:0xbfffda6c /& mys: 0xbfffda60
设备(iOS 5.1)结果;
(lldb)x`& mys` -fx
0x2fdfe2e4 :0xa1b1c1d1 0xf2e28292 0x09080706 0x01020304
& force16ByteBoundary:0x2fdfe2f0 /& some4Byte:0x2fdfe2ec /& mys: 0x2fdfe2e4
(新发现)
- On Simulator and Device;
- Building for Release or Debug does not make any difference for alignments.
- Local or global variables of "long long", double types are aligned to 8 byte boundary although they must be aligned to 4 byte boundary.
- There is no problem with global variables of structs.
- On Simulator;
- Local variables of structs are aligned to 8 byte boundary even when there is only a char member in the struct.
(修改)
我只能找到iOS here的“数据类型和数据对齐”。 (另外,它们可以从ILP32 alignments here.)
推断出来答案 0 :(得分:0)
通常,对齐属性仅影响结构内项的相对对齐。这允许向后兼容希望直接从网络或二进制文件将数据批量复制到结构中的代码。
对齐属性不会影响在堆栈上分配的局部变量的对齐方式。堆栈上的项目的排序和对齐不能得到保证,并且通常会针对设备的每个项目进行最佳对齐。因此,如果一个基于386的设备可以在单个操作中通过8字节对齐从内存中获取64位长的长度,它将会这样做。如果数据未完全对齐,某些处理器实际上会失去大量性能。某些处理器可能会因尝试读取未正确对齐的数据而抛出异常。