当位域宽度小于需要时,整数位域的值交替等于0或1

Value of integer bit field is alternately equal to 0 or 1 when bit field width is less than the needed

我正在测试 C 中的代码,其中我有意在结构中定义一个整数位字段( 变量 not_enough),宽度为 1,但分配的值需要 2或 3 位。 请务必注意,我从枚举中获取值。在此之后,我打印值。我希望得到等于 0 的整数的默认值。但我得到的是交替等于 0 或 1 的值。

你能解释一下为什么吗?

下面是代码:

#include <stdio.h>

typedef enum {
    FIRST = 9,
    SECOND = 8,
    THIRD = 7,
    FOURTH = 6,
    FIFTH = 5,
    SIXTH = 4,
    SEVENTH = 3,
    EIGHTH = 2
} directionValues;

struct {
    unsigned int enough : 3;
    unsigned int not_enough: 1; //intentionally limited to 1 bit
} test_bit;

int main(void) {

    test_bit.enough = EIGHTH;
    printf("Enough bits for variable. Value is %d\n",test_bit.enough);

    test_bit.not_enough = THIRD;
    printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);
    test_bit.not_enough = FOURTH;
    printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);
    test_bit.not_enough = FIFTH;
    printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);
    test_bit.not_enough = SIXTH;
    printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);
    test_bit.not_enough = SEVENTH;
    printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);
    test_bit.not_enough = EIGHTH;
    printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);

    return 0;
}

输出为:

Enough bits for variable. Value is 2

Not enough bits for variable. Value is 1

Not enough bits for variable. Value is 0

Not enough bits for variable. Value is 1

Not enough bits for variable. Value is 0

Not enough bits for variable. Value is 1

Not enough bits for variable. Value is 0

无论如何,什么是未定义的行为 - 你无法通过仅观察它来知道 C 中的某些东西是不是未定义的行为它可能是交替的 1 和 0 是未定义行为的一个例子。

但是,C 标准规定在这种情况下没有未定义的行为。通过取值模 2,将这些枚举的值转换为 1 位宽的无符号整数。引用 C11 6.3.1.3:

1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.

2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. 60)

3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

脚注 60 说明:

The rules describe arithmetic on the mathematical value, not the value of a given type of expression.

任何整数值都可以转换为 1 位的无符号 int 位域,而没有未定义的行为——甚至不是实现定义的。存储的值将是

  • 0,如果原值是偶数
  • 1、若原值为奇数

(偶数是0 + 2*k,奇数是1 + 2*k——这里的2k匹配*重复加减一个比新的可以表示的最大值类型" - 即 2 被添加或减去 |k| 次。

或者,如果原始数字是无符号的,则存储的值是最低有效位;如果原始数字是有符号的并且实现使用 2 的补码表示,则存储的值再次是最低有效位。

那是因为只有最后一位设置为您的变量,因为它只允许有 1 位。

你实际上是这样做的:

test_bit.not_enough = 7; //(0111) Bit 0 is 1
printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);
test_bit.not_enough = 6; //(0110) Bit 0 is 0
printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);
test_bit.not_enough = 5; //(0101) Bit 0 is 1
printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);
test_bit.not_enough = 4; //(0100) Bit 0 is 0
printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);
test_bit.not_enough = 3; //(0011) Bit 0 is 1
printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);
test_bit.not_enough = 2; //(0010) Bit 0 is 0
printf("Not enough bits for variable. Value is %d\n",test_bit.not_enough);

由于您只有 1 位可用内存,因此只有第一位 (LSB) 设置为您的变量。