LINUX.ORG.RU

битовые поля

 , ,


0

1

Всех приветствую.

Я нашел баг в GCC!!! (хотел засунуть в заголовок, но жалко скора)

В общем, я перестал понимать как работают битовые поля в Си. Вот пример. Есть байтовый массив:

uint8_t b[] = {0x32, 0x1A, 0x01, 0xE6,  0x24, 0x00, 0x22, 0x48 };

натягиваем вот такую структуру на этот массив:

#pragma pack (push, 1)
typedef struct obj_control_502_s                                
{                                                               
   unsigned object_id:         8;                          
   unsigned object_length:   7;                        
   unsigned heading:         11;                         
   unsigned speed_abs:     11;                       
   unsigned y_point1:       13;
   unsigned x_point1:       13;
   unsigned mode_signal1: 1;
   obj_control_502_t;         
 #pragma pack (pop) 

obj_control_502_t *c502 = (obj_control_502_t *)b;

Я делаю смелое предположение, что структурка будет плотноупакованной. И нужные мне поля соберутся из нужных мне бит.

Вывожу все это на экран:

printf("ID: %X, LEN: %X, H: %X, SPD: %X, Y: %X, X: %X, mode: %X\n",
      c502->object_id,
      c502->object_length ,
      c502->heading,
      c502->speed_abs,
      c502->y_point1,
      c502->x_point1,
      c502->mode_signal1
);    

У меня выводится:

32 1A 01 E6 24 00 22 48

ID: 32, LEN: 1A, H: 402, SPD: 139, Y: 1001, X: 1208, mode: 0

И это очевидно неверно!!!

Должно быть: ID: 32, LEN: D, H: 7, SPD: 4C4, Y: 1000, X: 1124, mode: 0

Кто сможет объяснить результат?

★★★★★
      0x48       0x22       0x00       0x24       0xE6       0x01       0x1A       0x32
0b01001000 0b00100010 0b00000000 0b00100100 0b11100110 0b00000001 0b00011010 0b00110010
  gfffffff   ffffffee   eeeeeeee   eeeddddd   ddddddcc   cccccccc   cbbbbbbb   aaaaaaaa

a (object_id)     =        0011'0010 = 0x32
b (object_length) =         001'1010 = 0x1a
c (heading)       =    100'0000'0010 = 0x402
d (speed_abs)     =    001'0011'1001 = 0x139
e (y_point1)      = 1'0000'0000'0001 = 0x1001
f (x_point1)      = 1'0010'0000'1000 = 0x1208
g (mode_signal1)  =                0 = 0x00
xaizek ★★★★★
()
Ответ на: комментарий от xaizek

шайтанама!

ID: 32, LEN: D, H: 7, SPD: 4C4, Y: 1000, X: 1124, mode: 0

перемудрил :(

yax123 ★★★★★
() автор топика
9 марта 2020 г.

Кто сможет объяснить результат?

Я.

Есть байтовый массив: … натягиваем вот такую структуру на этот массив: … Вывожу все это на экран:

Получаешь нарушение strict aliasing rule. Что есть UB. Компилятор может творить что угодно.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.