Я немного читал о битовых полях в C, о том, как стандарт C не устанавливает какой-либо конкретный порядок полей в машинном слове и т. Д.
Надеюсь, этот вопрос соответствует формату SO.
Мой вопрос заключается в том, будет ли моя структура (определение следующее) действительно работать так, как я ожидаю. Вот определение, которое я придумал, а затем я буду обсуждать, что я хочу:
typedef enum {
STATE_ONE,
STATE_TWO,
STATE_THREE,
STATE_FOUR
} __attribute__ ((packed)) State;
typedef struct MyStruct {
// One of State enum (maximum of 4 states).
unsigned state : 2;
// Remaining 30 bits are used differently depending on 'state'.
union {
// If 'state' is STATE_ONE (0), the remaining bits are an ID number.
unsigned id : 30;
/*
* For all other states, the remaining bits are the 2-tuple:
* (buffer A index, buffer B index).
*/
struct {
unsigned bufferAIdx : 16;
unsigned bufferBIdx : 14;
} __attribute__ ((packed)) index;
} __attribute__ ((packed));
} __attribute__ ((packed)) MyStruct;
(Это для gcc, таким образом, директивы __attribute__
).
Вы, вероятно, можете сказать, для чего я: в зависимости от значения поля 'state', я хочу использовать оставшиеся 30 бит для разных целей. Это должен быть либо идентификационный номер, либо два набора индексов в различных буферах. И каждый экземпляр MyStruct должен занимать максимум 5 байтов.
Так что я хочу иметь возможность сделать что-то на этот счет:
MyStruct a, b;
a.state = STATE_ONE;
a.id = 123456;
b.state = STATE_THREE;
b.index.bufferAIdx = 6;
b.index.bufferBIdx = 2;
В основном я ищу информацию о том, "правильно ли это делать". Другими словами, я неправильно использую идеи битовых полей / союзов здесь? Если вы собираетесь поддерживать этот код, будете ли вы в ужасе, увидев это? Или вы бы предпочли, чтобы весь объект данных хранился в типе uint32_t
и управлялся с помощью маскирования и сдвига?