2017-03-08 137 views
0

我有以下结构:如何将C结构与4字节边界对齐?

typedef struct LOG_EVENT 
{ 
    time_t time; 
    uint32_t count; 
    int32_t error_type; 
    uint16_t gm_state; 
    uint8_t gm_mode; 
    uint8_t mc_state; 
} LOG_EVENT; 

在32位的系统,所述结构的strict alignment是4字节,因此部件被分布在4字节边界对齐。在这种情况下没有添加填充,因为所有成员一起都是4字节对齐的。

但在64位系统上这不是真的,其中time_t是64位。这种情况下的strict alignment是8字节。

如何将对齐方式更改为4字节?我想在64位系统上跨4个字节的边界对齐,因为我想确保没有填充完成。

从海湾合作委员会的属性页https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html,它说,The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well

我没有看到packed属性接受任何参数。

另外,如果我使用如下的字节对齐,会造成任何问题,相对于4字节对齐:

typedef struct __attribute__ ((packed)) LOG_EVENT 
{ 
    time_t time; 
    uint32_t count; 
    int32_t error_type; 
    uint16_t gm_state; 
    uint8_t gm_mode; 
    uint8_t mc_state; 
} LOG_EVENT; 
+0

@yantantphil我不确定这是个好主意。 – Monku

+2

“在32位系统上,结构严格对齐是4字节” - 错误....不!任何平台上的对齐都不能保证。但随时提供一个参考标准说明不同。这是一个像您的其他问题一样的XY问题。 **为什么**你想要这种对齐?看起来你应该重新考虑你的整个设计。 – Olaf

+0

@Olaf我想要4字节对齐,因为我不希望编译器添加填充。如果你看看这个结构,考虑严格的对齐是8字节,最后增加4字节。 – Monku

回答

0

最直接的事情是...不使用time_t。仅使用固定宽度类型。

typedef struct LOG_EVENT 
{ 
    int32_t time; 
    uint32_t count; 
    int32_t error_type; 
    uint16_t gm_state; 
    uint8_t gm_mode; 
    uint8_t mc_state; 
} LOG_EVENT; 

你放弃处理符号的32位time_t(通常的范围之外时间戳的能力,但并非总是如此,1901-12-13T20:45:52Z通过2038-01-19T03:14:07Z ),但如果您尝试使用带有32位时间戳的磁盘上记录阵列(这是最合理的解释),那不是问题。

1

#pragma pack(4)将对齐设置为4个字节。

注意这个指令不是标准的一部分,这个标准最初是在MSVC中引入的,后来被gcc用来与微软的编译器兼容。

此外,请注意类型的大小,如time_t,size_t,并且所有指针类型都将在这些架构之间进行。如果你的意图是在这两种架构上运行的应用程序之间创建一个可理解的结构,这将是一个问题。

也知道使用64位应用程序没有任何好处,除了您可以处理超过4GB内存的事实,如果您不需要可以坚持使用32位的所有内存,没有罪。