结构填充编译标志

时间:2014-04-09 07:02:05

标签: ios gcc compiler-construction compiler-errors padding

typedef struct{
    char        t1;
    long long   t2;
    char        t3;
}struct_size_test;

printf("sizeof(long long)==[%ld]\n", sizeof(long long));
printf("sizeof(char)==[%ld]\n", sizeof(char));
printf("sizeof(struct_size_test)==[%ld]\n", sizeof(struct_size_test));

iOS和OS X gcc中struct_size_test的结果不同 iOS中的结果是

sizeof(long long)==[8]
sizeof(char)==[1]
sizeof(struct_size_test)==[24]

但OS X gcc的结果是

sizeof(long long)==[8]
sizeof(char)==[1]
sizeof(struct_size_test)==[16]

我用谷歌搜索了这个并找到了一些建议,即添加" -malign-double"作为gcc编译标志。 但它显示

clang: error: unknown argument: '-malign-double' [-Wunused-command-line-argument-hard-error-in-future]
clang: note: this will be a hard error (cannot be downgraded to a warning) in the future

知道如何同步iOS和OS X的结构填充? 非常感谢!

3 个答案:

答案 0 :(得分:2)

您可以使用预处理程序指令为结构指定字节对齐,因此编译器不会执行填充:

#pragma pack(1)

typedef struct{
char t1;
long long t2;
char t3;
}struct_size_test;

#pragma options align=reset

如果结构是在无法更改的头文件中定义的,请说test.h:

//test.h
typedef struct{
char t1;
long long t2;
char t3;
}struct_size_test;

当你包含test.h时,你可以这样做:

#pragma pack(1)
#include test.h
#pragma options align=reset

我在自己的代码中使用过这种方法。

请记住,上面的解决方案实际上不是编译器标志,而是一个预处理器指令,它具有与您请求的相同的效果。希望这可以帮助。

答案 1 :(得分:1)

我认为答案应该是你肯定不想这样做。

您可以尝试使用nneonneo的解决方案或将__attribute__((packed))添加到您的结构中,以使OS X和iOS上的结构大小相同,但请记住,这是一个编译器特定的功能,将使您的代码不那么便携

此外,如果您确实更改了填充,则由于未满足对齐要求,您的程序可能会在任一架构(尤其是iOS / ARM)上崩溃或运行效率较低。一些ARM体系结构(不确定iDevices)将不允许未对齐的读/写,如果运行速度较慢则会彻底崩溃(因为需要两次内存读取而不是一次)。

解决方法可能是使用最高的公共对齐(看起来是8),这会占用更多的空间。但这仍然是hacky和不便携。

你为什么要这样做呢?

编辑:nneonneo的回答可能应该是这样的:

typedef struct{
    char        t1 __attribute__ ((aligned (8)));
    long long   t2 __attribute__ ((aligned (8)));
    char        t3 __attribute__ ((aligned (8)));
} struct_size_test;

答案 2 :(得分:0)

您可以尝试添加显式类型属性来控制结构对齐:

typedef struct{
    char        t1;
    long long   t2;
    char        t3;
} struct_size_test __attribute__ ((aligned (8))); // aligned(8) = 8-byte alignment