c位字段在struct中使用long int的奇怪行为

时间:2013-07-01 19:01:28

标签: c++ c struct bit-fields

当我运行以下代码时,我正在观察奇怪的行为。 我通过使用结构创建一个位域,我想使用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

2 个答案:

答案 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>类型。

我还应该提到intunsigned intsigned int_Bool(或bool)以外的其他类型的位字段是实现定义的

答案 1 :(得分:1)

您的代码中有未定义的行为,因为您在不初始化结构的情况下检查text.x中的位。因为您没有初始化变量,所以它将包含随机数据。