Does it make sense to qualify bit fields as signed / unsigned?
问题:
回答1:
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.
回答2:
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.
回答3:
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 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.
回答4:
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.
回答5:
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
回答6:
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.
回答7:
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...
回答8:
According to this reference, it's possible:
http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc03defbitf.htm
回答9:
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.
回答10:
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 :)