Възможно ли е и правилно ли е да се образува съюз от битово поле в C?

Имам следния съюз и той работи правилно:

#pragma pack(1)
...
union
{
    uint8_t opcode;
    struct
    {
        uint8_t z : 3;
        uint8_t y : 3;
        uint8_t x : 2;
    };
}opcode;    

Размерът на обединението е точно един байт, според

printf ("%zu\n", sizeof opcode);  

Проблемът възниква, когато се опитам да направя обединение от битовото поле там:

union
{
    uint8_t opcode;
    struct
    {
        uint8_t z : 3;
        union
        {
            uint8_t y : 3;
            struct
            {
                uint8_t p : 2;
                uint8_t q : 1;
            };
        }y;
        uint8_t x : 2;
    };
}opcode;    

Резултатът от

printf ("%zu\n", sizeof opcode);  

е 3 байта. Разбира се, мога да заобиколя това с макроси, но възможно ли е изобщо?


person pugnator    schedule 20.03.2014    source източник


Отговори (2)


Не, не е възможно да има структури, които са големи части от байта.

Обосновка:

Трябва да е възможно да се направи указател към структура и най-малката адресируема единица е 1 байт.

Забележка: Това ограничение съществува във всички компилатори, които познавам. Не знам дали всъщност се изисква от стандарта C.

person Klas Lindbäck    schedule 20.03.2014

Вашият код ще декларира 3-байтова структура от данни, тъй като, както Клас вече посочи, структурата винаги се допълва до най-малката адресируема единица.

Но е възможно да направите това, което искате, като вградите множество структури от най-високо ниво в съюза и добавите подложка, когато е необходимо:

union {
    uint8_t opcode;
    struct {
        uint8_t z:3;
        uint8_t y:3;
        uint8_t x:2;
    };
    struct {
        uint8_t:3;
        uint8_t p:2;
        uint8_t q:1;
    };
} opcode;

Имайте предвид, че е възможно да декларирате битови полета без име за подпълване. Това е стандартна функция на езика C.

person CliffordVienna    schedule 20.03.2014
comment
Това е перфектно! Много елегантно решение. Благодаря много! - person pugnator; 20.03.2014