union typedef中的冗余字节

时间:2014-11-28 12:14:49

标签: c++ struct typedef unions

我使用以下结构格式化CAN消息的数据。 messageData.ptr用于进一步处理。部分部分用于更好的访问。 问题是,为什么messageData.srcSpecifier和messageData.data

之间还有两个字节
typedef union _MessagePureData_TypeDef
{
    signed int S32[1];
    unsigned int U32[1];
    unsigned short U16[2];
    signed short S16[2];
    unsigned char U8[4];
} messagePureData;

typedef union _MessageData_TypeDef
{
    unsigned char ptr[6];
    struct
    {
        unsigned char srcDevice;
        unsigned char srcSpecifier;
        messagePureData data;
    } section;
} messageData; 

示例:

messageData.section.srcDevice = 0xAA;
messageData.section.srcSpecifier = 0xBB;
messageData.section.data.U32  = 0x11223344;

结果messageData.ptr包含: [0xAA,0xBB,0x01,0x17,0x44,0x33]

所以从哪里来的是0x01和0x17 ??

3 个答案:

答案 0 :(得分:2)

对齐。
messagePureData总是与int对齐,大概可能是4个字节。这意味着section肯定与8个字节对齐,在srcSpecifierdata之间放置两个填充字节(因此整个struct对象的对齐为8,data为1 4)。另一方面,作为数组的ptr是连续的,因此它覆盖与两个填充字节相同的存储空间。

| ptr         | ptr + 1      | ptr + 2 | ptr + 3 | ptr + 4   | ptr + 5   |
|             |              |         |         |           |             
| srcDevice   | srcSpecifier | padding | padding | &data     | &data + 1 |   ... 

^                            ^                   ^
| Address is multiple of 8   |                   | Address is multiple of 4
                             |                   
                             | 
                             | Address is a multiple of two;
                             | Unfeasible address for data.

你可以打包结构来绕过这个。

答案 1 :(得分:0)

由于联合包含int个成员,因此它与int具有相同的对齐要求。如果需要,在结构的data成员之前添加填充以提供该对齐。

在您的平台上,似乎该要求是四个字节。在它之前的两个成员每个占用一个字节,因此需要两个以使其偏移量为四的倍数。这些不会初始化为任何特定值,因此如果您查看它们,您会看到任意值。

答案 2 :(得分:0)

messagePureData data字段的大小为32位。

编译器因此通过添加2个字节(a.k.a. padding )将其与32位地址对齐。

您可以使用#pragma pack来阻止编译器应用此重新对齐。

但请记住,访问此字段的汇编代码可能效率稍低。