开发者

Bit setting question

In C or C++, it's apparently possible to restrict the number of bits a variable has, so for example:

unsigned char A:1;
unsigned char B:3;

I am unfamiliar however with how it works specifically, so a number of questions:

If I have a class with the following variables:

unsigned char A:1;
unsigned char B:3;
unsigned char C:1;
unsigned char D:3;
  1. What is the above technique actually called?
  2. Is above class four bytes in size, or one byte in size?
  3. Are the variables treated as 1 (or 3) bits as shown, or as per the 'unsigned char', treated as a byte each?
  4. Is there someway of combining the bits to a centralised byte? So for example:

.

unsigned char MainByte;
unsigned char A:1; //Can this be made to point at the first bit in MainByte?
unsigned char B:3; //Etc etc
unsigned char C:1;
unsigned char D:3;
  1. Is there an article that covers this topic in more depth?
  2. If 'A:1' is treated like an entire byte, what is the point/purple of it?

Feel free to mention any other considerations (like compiler restric开发者_StackOverflowtions or other limitations).

Thank you.


What is the above technique actually called?

Bitfields. And you're only supposed to use int (signed, unsigned or otherwise) as the "type", not char.

Is above class four bytes in size, or one byte in size?

Neither. It is probably sizeof(int) because the compiler generates a word-sized object. The actual bitfields will be stored within a byte, however. It'll just waste some space.

Are the variables treated as 1 (or 3) bits as shown, or as per the 'unsigned char', treated as a byte each?

They represent only the bits specified, and will be packed as tightly as possible.

Is there someway of combining the bits to a centralised byte? So for example:

Use a union:

struct bits {
  unsigned A:1;
  unsigned B:3;
  unsigned C:1;
  unsigned D:3;
};

union SplitByte {
  struct bits Bits;
  unsigned char Byte[sizeof(struct bits)];
  /* the array is a trick so the two fields
     are guaranteed to be the same size and
     thus be aligned on the same boundary */
} SplitByteObj;

// access the byte
SplitByteObj.Byte[0]

// access a bitfield
SplitByteObj.Bits.B

Note that there are problems with bitfields, for example when using threads. Each bitfield cannot be accessed individually, so you may get errors if you try to use a mutex to guard each of them. Also, the order in which the fields are laid out is not clearly specified by the standard. Many people prefer to use bitwise operators to implement bitfields manually for that reason.

Is there an article that covers this topic in more depth?

Not many. The first few you'll get when you Google it are about all you'll find. They're not a widely used construct. You'll be best off nitpicking the standard to figure out exactly how they work so that you don't get bitten by a weird edge case. I couldn't tell you exactly where in the standard they're specified.

If 'A:1' is treated like an entire byte, what is the point/purple of it?

It's not, but I've addressed this already.


These are bit-fields.

The details of how these fields are arranged in memory are largely implementation-defined. Typically, you will find that the compiler packs them in some way. But it may take various alignment issues into account.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜