я наблюдаю странное поведение, когда я запускаю следующий код.
Я создаю битовое поле, используя структуру, где я хочу использовать 52 бита, поэтому я использую long int.
Размер long int в моей системе составляет 64 бита, я проверяю его внутри кода.
Каким-то образом, когда я пытаюсь установить один бит, он всегда устанавливает два бита. один из них — тот, который я хотел установить, а второй — индекс первого плюс 32.
Кто-нибудь может сказать мне, почему это?
#include <stdio.h>
typedef struct foo {
long int x:52;
long int:12;
};
int main(){
struct foo test;
int index=0;
printf("%ld\n",sizeof(test));
while(index<64){
if(test.x & (1<<index))
printf("%i\n",index);
index++;
}
test.x=1;
index=0;
while(index<64){
if(test.x & (1<<index))
printf("%i\n",index);
index++;
}
return 0;
}
Sry забыл опубликовать вывод, поэтому мой вопрос был в принципе не понятным …
Вывод, который он мне дает, следующий:
8
0
32
index
имеет тип int
, что, вероятно, 32 бита в вашей системе. Сдвиг значения на величину, большую или равную количеству битов в его типе, имеет неопределенное поведение.
+ Изменить index
в unsigned long
(сдвигаемые биты подписанные типы не рекомендуется). Или вы можете изменить 1<<index
в 1L << index
, или даже 1LL << index
,
Как уже отмечали другие, test
неинициализирован. Вы можете инициализировать его для всех нулей следующим образом:
struct foo test = { 0 };
Правильный printf
формат для size_t
является %zu
не %ld
,
И было бы неплохо изменить код, чтобы он не зависел от непереносимого предположения о том, что long
составляет 64 бита. Это может быть как 32 бита. Рассмотрите возможность использования uint_N_t
типы, определенные в <stdint.h>
,
Я должен также упомянуть, что битовые поля типов кроме int
, unsigned int
, signed int
, а также _Bool
(или же bool
) определяются реализацией.
У вас есть неопределенное поведение в вашем коде, когда вы проверяете биты в text.x
без инициализации структуры. Поскольку вы не инициализируете переменную, она будет содержать случайные данные.