Reputation: 2400
According to std::byte
's documentation on cppreference, the implementation of operator|
for std::byte
should be equivalent to
constexpr std::byte operator|(std::byte l, std::byte r) noexcept
{
return std::byte{ static_cast<unsigned>(l) | static_cast<unsigned>(r) };
}
(Operators &
, ^
, ~
should be implemented similarly)
Why do l
and r
need to get cast to int unsigned
if std::byte
's underlying type is char unsigned
?
Note: I'm aware that char unsigned{} | char unsigned{}
results in an int
because each operand gets promoted to int
before the bitwise or is applied; while unsigned{} | unsigned{}
returns an unsigned
and no promotion happens. However, I don't understand which issues may such a promotion cause in this context.
Upvotes: 1
Views: 1117
Reputation: 180510
For integer types that are smaller then an int
, they are promoted to an int
before the operator is applied. That means if you had
return std::byte{ l | r };
then you would have a signed integer. By using
return std::byte{ static_cast<unsigned>(l) | static_cast<unsigned>(r) }
You explicitly convert the operands to unsigned integers so that no promotion to int
happens.
This could make a difference before C++20 as signed integers were not required to use a two's complement representation unlike unsigned integer types.
Upvotes: 2