NoSenseEtAl
NoSenseEtAl

Reputation: 29996

Is bool required in C++ to be represented with 1 bit set when true/ 0 bits set when false

I was thinking about microoptimizing a function that returns 4 bools by using an union of uint32_t and bool[4], and then doing the popcnt instruction to see how many elements of the bool array are true.

But I do not know if the standard guarantees that bool is represented as number with only 1 bit set when true and 0 bits set when it is false.

If the answer is no then I have a follow up question: if it is not required is it required that representation is constant, e.g. if I have a test that checks that true bool casted to uint_8t is 1(and 0 for false) does that this means that every representation of bools in the program will behave the same.

note: I know that it is not required that bool is 1byte, but I can static_assert on that.

Upvotes: 3

Views: 589

Answers (1)

L. F.
L. F.

Reputation: 20569

I was thinking about microoptimizing a function that returns 4 bools by using an union of uint32_t and bool[4], and then doing the popcnt instruction to see how many elements of the bool array are true.

That will cause undefined behavior because accessing an inactive member of the union violates the object lifetime rules. You probably want to use a std::bitset<4> instead — it is designed for usage like this.

Note that std::bitset cannot directly be constructed from several bools, you may have to compose an unsigned long long first. Or you can use a helper function like this:

template <std::size_t N>
constexpr std::bitset<N> pack_bools(const bool (&arr)[N])
{
    static_assert(N <= std::numeric_limits<unsigned long long>::digits);

    unsigned long long num{0};
    for (std::size_t i = 0; i < N; ++i) {
        if (arr[i])
            num += 1LL << i;
    }
    return std::bitset<N>{num};
}

usage:

pack_bools({true, false, true, false}); // for example

(test)

But I do not know if the standard guarantees that bool is represented as number with only 1 bit set when true and 0 bits set when it is false.

No, there's no guarantee like that. [basic.fundamental]/10:

Type bool is a distinct type that has the same object representation, value representation, and alignment requirements as an implementation-defined unsigned integer type. The values of type bool are true and false. [ Note: There are no signed, unsigned, short, or long bool types or values. — end note ]

There's no more guarantee about the value representation.

If the answer is no then I have a follow up question: if it is not required is it required that representation is constant, e.g. if I have a test that checks that true bool casted to uint_8t is 1(and 0 for false) does that this means that every representation of bools in the program will behave the same.

No, there's no such guarantee either.

Upvotes: 9

Related Questions