views:

2447

answers:

8

Does is make sense to qualify bit fields as signed / unsigned?

A: 

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 :)

workmad3
Wrong. You get -1, -0, +0, +1. Two bits, four states.
Thorsten79
probably something like -2, -1, 0, 1 makes more sense, you almost never need a -0
davr
http://en.wikipedia.org/wiki/−0_(number)
Thorsten79
Um. I don't think that the C standard includes the notion of negative zero in integer arithmetic.
ΤΖΩΤΖΙΟΥ
Actuallly, from a single bit you get only two states (no surprise if you understand twos complement arithmetic) Those are 0 and -1.
Nils Pipenbrinck
@Nils: Yes, from a single bit you get only two states, and from two bits you get four states. If you meant your comment as a reply to workmad3, perhaps you should prefix your comment with "@workmad3".
ΤΖΩΤΖΙΟΥ
I have the feeling you belong to the class of people who comes up with the idea of a tristate boolean...
freespace
Hrm, actually rereading this post leads to me to think this was a joke we all missed... a ternary digit is a tit...
freespace
ah, finally someone sees the joke... perhaps next time I should be a bit more obvious :P
workmad3
and yes, my original basis was that there was a sign bit and a bitfield bit and that 0 and -0 were equivalent (as is usual in signed integers), which collapses down to tristate logic.
workmad3
+2  A: 

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.

Tanktalus
There are szenarios where it is usefull. In computational geometry you often have to store informations like "next, previous, none, the-same". That meks exactly two bits. It it happends that you can compress your structure to a nice size such as 2^n you may get a nice to have peformance boost.
Nils Pipenbrinck
+2  A: 

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.

wnoise
+9  A: 

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.

Chris Young
+1  A: 

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.

ΤΖΩΤΖΙΟΥ
A: 

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.

A: 

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.

Oliver