简体   繁体   中英

Does ANSI C support signed / unsigned bit fields?

将位字段限定为有符号/无符号是否有意义?

The relevant portion of the standard (ISO/IEC 9899:1999) is 6.7.2.1 #4:

A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or some other implementation-defined type.

Yes. An example from here :

struct {
  /* field 4 bits wide */
  unsigned field1 :4;
  /*
   * unnamed 3 bit field
   * unnamed fields allow for padding
   */
  unsigned        :3;
  /*
   * one-bit field
   * can only be 0 or -1 in two's complement!
   */
  signed field2   :1;
  /* align next field on a storage unit */
  unsigned        :0;
  unsigned field3 :6;
}full_of_fields;

Only you know if it makes sense in your projects; typically, it does for fields with more than one bit, if the field can meaningfully be negative.

It's very important to qualify your variables as signed or unsigned. The compiler needs to know how to treat your variables during comparisons and casting. Examine the output of this code:

#include <stdio.h>

typedef struct
{
    signed s : 1;
    unsigned u : 1;
} BitStruct;

int main(void)
{
    BitStruct x;

    x.s = 1;
    x.u = 1;

    printf("s: %d \t u: %d\r\n", x.s, x.u);
    printf("s>0: %d \t u>0: %d\r\n", x.s > 0, x.u > 0);

    return 0;
}

Output:

s: -1    u: 1
s>0: 0   u>0: 1

The compiler stores the variable using a single bit, 1 or 0. For signed variables, the most significant bit determines the sign (high is treated negative). Thus, the signed variable, while it gets stored as 1 in binary, it gets interpreted as negative one.

Expanding on this topic, an unsigned two bit number has a range of 0 to 3, while a signed two bit number has a range of -2 to 1.

I don't think Andrew is talking about single-bit bit fields. For example, 4-bit fields: 3 bits of numerical information, one bit for sign. This can entirely make sense, though I admit to not being able to come up with such a scenario off the top of my head.

Update: I'm not saying I can't think of a use for multi-bit bit fields (having used them all the time back in 2400bps modem days to compress data as much as possible for transmission), but I can't think of a use for signed bit fields, especially not a quaint, obvious one that would be an "aha" moment for readers.

Most certainly ANSI-C provides for signed and unsigned bit fields. It is required. This is also part of writing debugger overlays for IEEE-754 floating point types [[1][5][10]], [[1][8][23]], and [[1][10][53]]. This is useful in machine type or network translations of such data, or checking conversions double (64 bits for math) to half precision (16 bits for compression) before sending over a link, like video card textures.

// Fields need to be reordered based on machine/compiler endian orientation

typedef union _DebugFloat {
   float f;
   unsigned long u;
   struct _Fields {
        signed   s :  1;
        unsigned e :  8;
        unsigned m : 23;
      } fields; 
   } DebugFloat;

Eric

Yes, it can. C bit-fields are essentially just limited-range integers. Frequently hardware interfaces pack bits together in such away that some control can go from, say, -8 to 7, in which case you do want a signed bit-field, or from 0 to 15, in which case you want an unsigned bit-field.

One place where signed bitfields are useful is in emulation, where the emulated machine has fewer bits than your default word.

I'm currently looking at emulating a 48-bit machine and am trying to work out if it's reasonable to use 48 bits out of a 64-bit "long long" via bitfields... the generated code would be the same as if I did all the masking, sign-extending etc explicitly but it would read a lot better...

Bit masking signed types varies from platform hardware to platform hardware due to how it may deal with an overflow from a shift etc.

Any half good QA tool will warn knowingly of such usage.

if a 'bit' is signed, then you have a range of -1, 0, 1, which then becomes a ternary digit. I don't think the standard abbreviation for that would be suitable here, but makes for interesting conversations :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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