2017-01-05 9 views
0

В VStudio 2010, я пытаюсь создать союз, чтобы получить доступ к стоимости 2-байтовой удобно:VStudio C++ выравнивание битового поля в союзе

#pragma pack(push,1) // disable padding 
typedef struct { 
    uint8_t r:3; 
    uint8_t g:3; 
    uint8_t b:3; 
}tsRgb; 

typedef union { 
    uint16_t raw; 
    tsRgb rgb; 
}tPixelData; 
#pragma pack(pop) 

int main(){ 
    tPixelData pixel; 
    pixel.raw = 0xABE5; 
    return 0; 
} 

Я ожидал увидеть pixel.r = 5, pixel.g = 4, pixel.b = 7. r и g в порядке, но b равно 3.

Что я делаю неправильно? Я предполагаю, что я неправильно присваиваю биты?

+0

См. Это http://stackoverflow.com/questions/6043483/why-bit-endianness-is-an-issue-in-bitfields/6044223#6044223 – Lundin

+0

Стандарт почти ничего не гарантирует о битовых полях. И гарантируются только типы '((un)) int' и' _Bool'. – Olaf

+0

downvoter сообщите пожалуйста. Спасибо. –

ответ

4

Третье поле будет в отдельном байте.

В VC++ битовые поля не пересекают границы базового типа. Когда вы использовали 3 + 3 бита, осталось только 2, поэтому следующее поле будет использовать 3 бита из нового байта.

Это может сработать лучше, если вы используете uint16_t вместо uint8_t.

«Отключить заполнение» работает на уровне байта, а не на уровне бит.

+0

хороший! Работает сейчас, спасибо! –

+0

* Битовые поля не пересекают границы базового типа * Это определяется реализацией. Хотя они не могут пересекать границы в реализации VStudio, используемой OP, бит-поля очень хорошо могут пересекать границы базовых блоков хранения. Бит-поля * чрезвычайно * зависимы от реализации и * чрезвычайно * не переносятся. –

+1

@Andrew - Хорошо, я добавил разъяснение, что ответ для системы, которую использует OP. –

3

Использование бит-полей, как вы хотите, принципиально проблематично. Per the C Standard, 6.7.2.1 Структура и объединение спецификаторы, пункт 11 (так как ваш вопрос также помечено C):

Реализация может выделить любой адресуемый блок хранения больших достаточно провести битовое поле. Если остается достаточно места, бит-поле , которое сразу же следует за другим битовым полем в структуре, должно быть , упакованное в соседние биты того же блока. Если недостаточно места , остается ли бит-поле, которое не подходит, помещается в следующий блок или перекрывает смежные единицы . Порядок распределения бит-полей в пределах единицей (от высокого порядка до низкого или низкого порядка) является , определяемый реализацией. Выравнивание адресного хранилища не определено.

Макет и выравнивание битов в битовом поле определяются реализацией. Поля могут или не могут пересекать границы единицы хранения, они могут храниться в любом порядке.

Они не являются переносными вообще.

+0

Они не являются переносимым способом сопоставления некоторого битового формата. Они * являются * переносимым способом сокращения потребления памяти в структуре (и это все, для чего они должны использоваться). –