Carbon
Carbon

Reputation: 3943

Can an enum be reduced to its bit size in C++?

Given the following - can I get sizeof(A) to be 1? Right now I'm getting 8, but I'd like A to be equal in layout to Z - as the enum only has one bit of data.

enum BOOL { x , y};

struct A {
    BOOL b : 1;
    unsigned char c : 7;
};
struct Z {
    unsigned char r : 1;
    unsigned char c : 7;
};

int main()
{

    A b;
    b.b = x;
    std::cout << b.b  << "," << sizeof(A) << ","<< sizeof(Z) << std::endl;
    return 0;
}

Upvotes: 3

Views: 141

Answers (2)

NathanOliver
NathanOliver

Reputation: 180630

The issue here is that BOOL will use an int as the underlying type by default. Since it uses an int, it is padding the struct out to have a size of 8 as that will keep the int part of the struct nicely aligned.

What you can do though is specify that you don't want an int, but instead want an unsigned char so that it can pack both bitfields in a single member. This isn't guaranteed, but makes it much more likely to happen. Using

enum BOOL : unsigned char { x , y};

makes A have a sizeof 1 in GCC, Clang and MSVC

Upvotes: 6

eerorika
eerorika

Reputation: 238351

You can use bool as the underlying type of the enum:

enum BOOL : bool { x , y};

Given this, on my system, sizeof(A) is 1. I don't think that is guaranteed given that much of bit field structure is implementation defined, and bool itself is technically not guaranteed to have size 1.

Using unsigned char is another alternative, which may be handled better with the adjacent unsigned char bitfield member on some implementations. Unfortunately though, GCC for example warns warning: 'A::b' is too small to hold all values of 'enum BOOL' which is technically a false positive, since one bit is sufficient to represent 0 and 1.

Upvotes: 1

Related Questions