2014-04-09 72 views
1
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了这一点,并发现了一些建议,增加“-malign双”的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结构的填充? 非常感谢!

+1

你想在这里做什么?如果你正在尝试使用结构打包技术,那么很可能你正在尝试一些非常错误或愚蠢的事情。 – gnasher729

回答

0

我想答案应该是你肯定不希望这样做。

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

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

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

为什么你试图做到这一点呢?

编辑:nneonneo的答案或许应该是这样的:

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

不,我不能使用__attribute __((packed)),结构尺寸必须与iOS显示的完全相同。该结构已经被许多团队成员使用。所以结构不能改变。 – srjohnhuang

+0

为什么它必须是特定的大小?你在汇编代码中使用结构吗? – tangrs

+0

将它用于TCP通信,因此它位于两个不同的平台上。而TX平台是固定的,我们不能改变它。 – srjohnhuang

0

你可以尝试添加一个明确的类型属性来控制结构对齐:

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

感谢您的快速建议,但它仍然显示sizeof(struct_size_test)== [16]。很奇怪! – srjohnhuang

+0

我认为对齐属性应该发送给各个成员。 – tangrs

+0

@tangrs哦,太棒了!我刚看到这个。你是正确的,对齐属性应该去个别成员。谢谢您的帮助! 你知道为什么'-malign-double'标志不起作用吗? – srjohnhuang

1

您可以使用预处理指令指定的结构,从而没有填充将由编译器来实现字节对齐:

#pragma pack(1)

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

#pragma options align=reset

如果该结构中不能被改变的头文件中定义,说测试。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

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

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