paolo
paolo

Reputation: 2400

std::byte bitwise operators |, &, ^, ~: why cast to unsigned int?

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

Answers (1)

NathanOliver
NathanOliver

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

Related Questions