0

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

4

2 回答 2

5

index是 type int,在您的系统上可能是 32 位。将值移位大于或等于其类型中位数的量具有未定义的行为。

更改indexunsigned long(不建议对有符号类型进行位移位)。或者你可以改成1<<index1L << index甚至1LL << index

正如其他人指出的那样,test未初始化。您可以像这样将其初始化为全零:

 struct foo test = { 0 };

的正确printf格式size_t%zu,不是%ld

修改代码也不错,因此它不依赖于long64 位的不可移植假设。它可以窄至 32 位。考虑使用中uint_N_t定义的类型<stdint.h>

我还应该提到,除intunsigned intsigned int_Bool(或bool)之外的类型的位字段是实现定义的。

于 2013-07-01T19:07:56.430 回答
1

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

于 2013-07-01T19:03:50.767 回答