如何将C结构与4字节边界对齐?

时间:2017-03-08 00:47:24

标签: c gcc

我有以下结构:

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字节边界,因为我想确保没有填充。

在gcc属性页面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;

2 个答案:

答案 0 :(得分:1)

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

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

另外,请注意time_tsize_t等类型的大小,所有指针类型都将在这些体系结构之间。如果您打算在这两种体系结构上运行的应用程序之间建立一个可理解的结构,那么这将是一个问题。

另外要知道使用64位应用程序没有任何好处,除了你可以处理超过4GB的内存,如果你不需要所有那些内存你可以坚持32位,没有在那里犯罪。

答案 1 :(得分: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位时间戳的磁盘记录阵列,这是最合理的解释,那不是问题。