Signed bit field represetation

前端 未结 2 1442
傲寒
傲寒 2020-12-03 19:01

I made a bit field with a field sized 1 bit, and used int instead of unsigned. Later on when i tried to check the value of the field i found that t

相关标签:
2条回答
  • 2020-12-03 19:58

    When you call a variadic argument function (like printf) some arguments are promoted. For example bit-fields undergoes an integer promotion where it is promoted to an ordinary int value. That promotion brings with it sign extension (because your base type for the bit-field is signed). This sign extension will make it -1.

    When using bit-fields, always use unsigned types as the base.

    0 讨论(0)
  • 2020-12-03 20:03

    You shouldn't ever use plain int as the bitfield type if you're expecting something about the value besides that it can hold n bits - according to the C11 standard it is actually implementation-defined whether int in a bit-field is signed or unsigned 6.7.2p5:

    5 Each of the comma-separated multisets designates the same type, except that for bit-fields, it is implementation-defined whether the specifier int designates the same type as signed int or the same type as unsigned int.

    In your case the int designates the same type as signed int; this is the default in GCC:

    Whether a “plain” int bit-field is treated as a signed int bit-field or as an unsigned int bit-field (C90 6.5.2, C90 6.5.2.1, C99 and C11 6.7.2, C99 and C11 6.7.2.1).

    By default it is treated as signed int but this may be changed by the -funsigned-bitfields option.

    Then it is implementation defined whether the signed numbers are in one's complement, or two's complement - if they're in one's complement, then the only value that can be stored in 1 bit is the sign bit, thus 0; so signed bit field of one bit doesn't make sense on one's complement. However, your system uses 2's complement - this is e.g. what GCC always uses:

    Whether signed integer types are represented using sign and magnitude, two’s complement, or one’s complement, and whether the extraordinary value is a trap representation or an ordinary value (C99 and C11 6.2.6.2).

    GCC supports only two’s complement integer types, and all bit patterns are ordinary values.

    and thus the bit values 1 and 0 are interpreted in terms of signed two's complement numbers: the former has sign bit set, so it is negative (-1) and the latter doesn't have a sign bit set so it is non-negative (0).

    Thus for a signed bit-field of 2 bits, the possible bit patterns and their integer values on a 2's complement machine are

    • 00 - has int value 0
    • 01 - has int value 1
    • 10 - has int value -2
    • 11 - has int value -1

    In an n-bit-field, the minimum signed number is - 2^(n - 1) and the maximum is 2^(n-1) - 1.

    Now, when arithmetic is performed on a signed integer operand whose rank is less than int, it is converted to an int first, and thus the value -1 is sign-extended to full-width int; the same happens for default argument promotions; the value is sign-extended to a (full-width) int when it is passed in to printf.

    Thus if you expect a sensible value from one bit bitfield, use either unsigned bit: 1; or alternatively if this is to be understood as a boolean flag, _Bool bit: 1;

    0 讨论(0)
提交回复
热议问题