结构填充编译标志

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] 

我GOOGLE了这个,并发现一些build议,添加“-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的结构填充? 非常感谢!

我认为答案应该是你绝对不想这样做。

您可以尝试nneonneo的解决scheme或添加__attribute__((packed))到您的结构,使结构在OS X和iOS的大小相同,但请记住这是一个编译器特定的function,将使您的代码更便携

而且,如果你确实改变了填充,那么你的程序可能会在两种架构(特别是iOS / ARM)上崩溃或者运行效率不高,因为不能满足alignment要求。 一些ARM体系结构(不确定iDevices)将不允许未alignment的读/写操作,如果运行速度较慢(因为需要两次内存读取而不是一次),将彻底崩溃。

解决方法可能是使用最高的常见alignment(似乎是8),这只需要更多的空间。 但是,这仍然是hacky和不可移植的。

你为什么要这样做?

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

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

您可以使用预处理器指令来为结构指定字节alignment方式,因此编译器不会执行填充操作:

#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

我在我自己的代码中使用了这个方法。

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

您可以尝试添加显式的types属性来控制结构alignment:

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