结构数据对齐。大小必须是存在的最大类型的整数倍?

时间:2015-01-29 21:18:57

标签: c struct

我正在制作一个通过串口发送/接收数据的GUI。数据包含在结构中定义的消息,如下所示:

typedef struct
{
    uint8_t a;
    uint8_t b;
    uint8_t c;
    uint16_t d[3];
    uint16_t e;
} MyMsg_t;

我也在使用union,因为它使我能够更容易地设置数据字段并能够逐字节发送它。工会看起来像这样:

typedef union
{
    MyMsg_t msg;
    uint8_t array[MyMsgLength];
} MyMsg;

我现在尝试将一些数据添加到这样的消息中:

MyMsg msg;

msg.msg.a    = (uint8_t) 1;
msg.msg.b    = (uint8_t) 2;
msg.msg.c    = (uint8_t) 3;
msg.msg.d[0] = (uint16_t) 4;
msg.msg.d[1] = (uint16_t) 5;
msg.msg.d[2] = (uint16_t) 6;
msg.msg.e    = (uint16_t) 7;

我通过串行总线按字节传输它,接收端是:

1 2 3 19 4 0 5 0 6 0 7

(由于总线,c到e中的数据相反)

这看起来像结构实际上是:

typedef struct
{
    uint8_t a; //1
    uint8_t b; //2
    uint8_t c; //3
    //uint8_t x //19
    uint16_t d[3];
    uint16_t e;
} MyMsg_t;

从这里我可以假设它在C标准的某个地方说结构必须是最小n * sizeof(uint16_t)在这种情况下,因为我们不能拥有例如结构中最大类型的3.5,但它有是一个整数?

我猜这就是所谓的填充?有没有办法强制结构为n * sizeof(uint8_t),即使存在更大的类型?

我知道如何避免这种情况,但它不需要使用联合和更多代码。有没有办法用最少的代码干预来优雅地避免这个问题?

1 个答案:

答案 0 :(得分:2)

如果机器也不要忘记字节顺序,这就是为什么这样做不是推荐的做法。如果您不关心字节序或以其他方式处理它,那么这种方法是可以接受的。

您可以更改对齐以消除填充。但是如何完成取决于编译器:

其他编译器可能有其他选择或方法来完成同样的事情。