C++ does the integer size matter when using bitfields?

Viewed 122

Other than signed or unsigned, to what degree does the type matter for bitfields, if at all?

For example what is the difference between:

unsigned char a : 3;
std::uint64_t b : 3;

I'm guessing as long as the bitfield is not larger than the type, it doesn't matter.

2 Answers

It's up to the compiler to decide how to lay out those values. The resulting object must be large enough to hold values that fit in the number of bits for the bitfield. For example, struct { std::unit64_t b : 8 } can be 8 bits in size; it is not required to be large enough to hold 64 bits.

But each bitfield has a type, and the type can affect the program's behavior. Here's a simple example:

#include <iostream>

void f(char) {
    std::cout << "char\n";
}

void f(int) {
    std::cout << "int\n";
}
struct a {
    char a : 3;
    int b : 3;
};

int main()
{
    a obj;
    f(obj.a);
    f(obj.b);
    return 0;
}

The (fully portable) output is:

[temp]$ clang++ test.cpp
[temp]$ ./a.out
char
int
[temp]$ 

C++ does the integer size matter when using bitfields?

Yes, it does.

For example what is the difference between:

unsigned char a : 3;
std::uint64_t b : 3;

The type of the first bit field is unsigned char and the type of the other bit field is std::uint64_t. On most systems these types have a different size.

Does that have any practical effect

Here is a simple example demonstrating a practical effect:

struct a {
    unsigned char a : 3;
};

struct b {
    std::uint64_t b : 3;
};

int main()
{
    std::cout << sizeof(a) << ' ' << sizeof(b);
}
Related