当我运行以下代码时,我正在观察奇怪的行为。 我通过使用结构创建一个位域,我想使用52位,所以我使用long int。 我的系统上long int的大小是64位,我在代码中检查它。 不知怎的,当我尝试设置一位时,它设置了两位。其中一个是我想要设置的,第二个是第一个加上32的索引。 Cann任何人都告诉我,为什么会这样?
#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
答案 0 :(得分:5)
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
)以外的其他类型的位字段是实现定义的
答案 1 :(得分:1)
您的代码中有未定义的行为,因为您在不初始化结构的情况下检查text.x
中的位。因为您没有初始化变量,所以它将包含随机数据。