工会内部结构

时间:2018-11-25 05:32:40

标签: c struct unions packing

我遇到了以下c代码。

union packet_t {
    uint8_t raw[10];
    struct {
        union {
            uint16_t number;
            uint8_t number_byte[2];
        };
        union {
            uint32_t size;
            uint16_t size_word[2];
            uint8_t size_byte[4];
        };
        uint8_t body[4];
    };
} packet;

当我尝试对其进行测试时,我遇到了一些奇怪的行为,希望有人可以帮助我找出此定义的问题所在。我做了一些搜索,但是没有类似的问题。

这是我尝试过的:

uint8_t test1[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a};
int i = 0;
for(i = 0; i < sizeof(test1); i++)
{
    packet.raw[i] = test1[i];
}

printf("packet.size_word[0]=0x%04x\n", packet.size_word[0]);
printf("packet.size_word[1]=0x%04x\n", packet.size_word[1]);

输出为

packet.size_word[0]=0x0605
packet.size_word[1]=0x0807

它完全错过了0x03和0x04。

当我使用以下定义(删除“ uint32_t size;”)时,它可以正常工作。

union packet_t {
    uint8_t raw[10];
    struct {
        union {
            uint16_t number;
            uint8_t number_byte[2];
        };
        union {
            uint16_t size_word[2];
            uint8_t size_byte[4];
        };
        uint8_t body[4];
    };
} packet;

以下是输出:

packet.size_word[0]=0x0403
packet.size_word[1]=0x0605

有人知道为什么会这样吗?我以为联合中的项目总是占据相同的内存位置。

这是link for the code.

original Code is here.

--------------------------更新11/25/2018 --------------- ------------------

所以我有信心现在是结构填充,并且取决于CPU架构。

我在Arduino上使用Atmega328p(8位MCU)进行了测试,它的工作原理很吸引人。由于MCU每次处理1个字节,因此没有结构填充。

但是,正如@selbie提到的那样,该代码根本不可移植,在编写此类代码时,我们必须考虑CPU架构和环境。最简单的解决方案是不使用它。

进一步阅读:

C – Structure Padding

Structure padding and packing

0 个答案:

没有答案