msc
msc

Reputation: 34608

Multiple adjacent bit fields in C++

I saw multiple adjacent bit fields while browsing cppreference.

unsigned char b1 : 3, : 2, b2 : 6, b3 : 2;

So,

Upvotes: 2

Views: 1441

Answers (4)

0xF
0xF

Reputation: 3708

One reason is to reduce memory consumption when you don't need full integer type range. It only matters if you have large arrays.

struct Bytes
{
    unsigned char b1; // Eight bits, so values 0-255
    unsigned char b2;
};
Bytes b[1000000000]; // sizeof(b) == 2000000000

struct Bitfields
{
    unsigned char b1 : 4; // Four bits, so only accommodates values 0-15
    unsigned char b2 : 4;
};

Bitfields f[1000000000]; // sizeof(f) == 1000000000

The other reason is matching binary layout of certain hardware or file formats. Such code is not portable.

Upvotes: 0

msc
msc

Reputation: 34608

According to c++draft :

3 A memory location is either an object of scalar type or a maximal sequence of adjacent bit-fields all having nonzero width.[ Note: Various features of the language, such as references and virtual functions, might involve additional memory locations that are not accessible to programs but are managed by the implementation.— end note ]Two or more threads of execution ([intro.multithread]) can access separate memory locations without interfering with each other.

Upvotes: 0

Shivendra Agarwal
Shivendra Agarwal

Reputation: 688

Multiple adjacent bit fields are usually packed together (although this behavior is implementation-defined)

If you want compiler to not add padding or perform structure alignment during multiple bit field allocation you can compile them in a single variable.

struct x
{
  unsigned char b1 : 4;  // compiler will add padding after this. adding to the structure size.
  unsigned char b2 : 3; // compiler will add padding here too!  sizeof(x) is 2.
}


struct y
{
    unsigned char b1 : 4, : 3;   // padding will be added only once.  sizeof(y) is 1
}

Or if you want to allocate bigger bit field in a single variable

struct x
{
    unsigned char b1 :9;   //warning: width of 'x::b1' exceeds its type
};


struct y
{
    unsigned char b1 :6, :3;   //no warning
};

Upvotes: 0

Anton Malyshev
Anton Malyshev

Reputation: 8861

Obviously, to consume less memory working with bitwise operations. That may be significant for embedded programming, for example.

You can also use std::vector<bool> which can (and usually does) have bitfield implementation.

Upvotes: 1

Related Questions