简体   繁体   English

c位字段在结构中具有长整数的奇怪行为

[英]c bitfields strange behaviour with long int in struct

i am observing strange behaviour when i run the following code. 运行以下代码时,我观察到奇怪的行为。 i create a bitfield by using a struct, where i want to use 52 bits, so i use long int. 我通过使用结构创建一个位域,我想使用52位,所以我使用long int。 The size of long int is 64 bits on my system, i check it inside the code. 在我的系统上,long int的大小为64位,我在代码内对其进行了检查。 Somehow when i try to set one bit, it alwas sets two bits. 不知何故,当我尝试设置一位时,它总是设置了两位。 one of them is the one i wanted to set and the second one is the index of the first one plus 32. Cann anybody tell me, why is that? 其中一个是我要设置的值,第二个是第一个值加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 forgot to post the output, so my question was basicly not understandable... The Output it gives me is the following: Sry忘记发布输出,因此我的问题基本上是无法理解的...它给我的输出如下:

8 8

0 0

32 32

index is of type int , which is probably 32 bits on your system. indexint类型,在您的系统上可能是32位。 Shifting a value by an amount greater than or equal to the number of bits in its type has undefined behavior. 将值移位大于或等于其类型的位数的位数具有未定义的行为。

Change index to unsigned long (bit-shifting signed types is ill-advised). index更改为unsigned long (不建议使用移位型带符号类型)。 Or you can change 1<<index to 1L << index , or even 1LL << index . 或者,您可以将1<<index更改为1L << index ,甚至更改为1LL << index

As others have pointed out, test is uninitialized. 正如其他人指出的那样, test尚未初始化。 You can initialize it to all zeros like this: 您可以像这样将其初始化为全零:

 struct foo test = { 0 };

The correct printf format for size_t is %zu , not %ld . size_t的正确printf格式为%zu ,而不是%ld

And it wouldn't be a bad idea to modify your code so it doesn't depend on the non-portable assumption that long is 64 bits. 修改您的代码并不是一个坏主意,因此它不取决于long为64位的不可移植的假设。 It can be as narrow as 32 bits. 它可以窄至32位。 Consider using the uint_N_t types defined in <stdint.h> . 考虑使用<stdint.h>定义的uint_N_t类型。

I should also mention that bit fields of types other than int , unsigned int , signed int , and _Bool (or bool ) are implementation-defined. 我还应该提到,除intunsigned intsigned int_Bool (或bool )之外的其他类型的位字段是实现定义的。

You have undefined behavior in your code, as you check the bits in text.x without initializing the structure. 您在代码中具有未定义的行为,因为您在不初始化结构的情况下检查了text.x的位。 Because you don't initialize the variable, it will contain random data. 因为您没有初始化变量,所以它将包含随机数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM