Структура внутри союза - PullRequest
       54

Структура внутри союза

0 голосов
/ 25 ноября 2018

Я столкнулся со следующим кодом 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;"), оно работает нормально.

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

ДелаетКто-нибудь знает, почему это происходит?Я думал, что элементы в union всегда занимают одно и то же место в памяти.

Вот ссылка для кода.

Оригинальный код здесь.

-------------------------- Обновление 25.11.2008 ---------------------------------

Так что я уверен, что теперь это заполнение структуры, и оно зависит от архитектуры процессора.

Я тестировал на Arduino с Atmega328p (8-битный MCU), он работает как шарм.Не было никакого заполнения структуры, так как каждый раз процесс MCU обрабатывал 1 байт.

Однако код вообще не переносим, ​​как упоминал @selbie, при написании такого кода мы должны учитывать архитектуру процессора и среду.Самое простое решение - не использовать его.

Дополнительная информация:

C - Заполнение структуры

Заполнение структуры и набивка

...