Daniel V.
Daniel V.

Reputation: 383

Why std::optional<bool> uses two bytes?

If C++ allows bool to use any bit, What stops C++ from optimizing std::optionalto use 1 byte and use two bits for representing has_value and value()? Sure, we would use a mask, but in modern processors it won't hurt perf.

Upvotes: 4

Views: 2016

Answers (1)

bolov
bolov

Reputation: 75854

This:

constexpr const T& operator*() const&;
constexpr T& operator*() &;
constexpr T&& operator*() &&;

Makes what you want impossible. operator* needs to return a reference to the held object.


Diving more into why you can't do that:

Idea 1: store an unsigned char (or std::byte)

This way you can manipulate the bits as you please. You can even convert and return a bool prvalue.

But you cannot return a reference as the operator* requires.

Aliasing it (i.e. return reinterpret_cast<bool&>(m_byte) is illegal and again will result in Undefined Behavior (regardless if bool is one byte or not or if it has the same alignment or not).

Creating another bool object (either a local variable or a prvalue) and returning a reference to that will either not compile or return a dangling reference.

Ideea 2: store a bool

And manipulate its bits in such way that the bool makes sense when the optional has value. Something like:

bit pattern has value bool value
0000.0000 T F
0000.0001 T T
0000.0010 F N/A

The first problem with this is that bool is not guaranteed to be 1 byte.

But even on systems where bool is 1 byte you can't do it. The only valid values a bool type can have are true and false. Any attempt to create a 3rd value (either via bit manipulation or aliasing etc.) will result in Undefined Behavior.

Upvotes: 8

Related Questions