Hello Mastodon!

Since this is my first post, I thought I'd share some incredibly niche C++ trivia / pedantry:

For an enum whose enumerators all have the value 0, C++ asks us to imagine a hypothetical integer type with minimal width that can represent 0 (https://eel.is/c++draft/dcl.enum#8.sentence-2). This means we must consider the case where the width is 0. For an unsigned integer type, this gives a range of representable values of [0, 0], and that's the type we pick. But before we can determine that that's minimal, we must also consider a signed integer type with a width of 0, for which we get a range of representable values of [-Β½, -Β½]! (https://eel.is/c++draft/basic.fundamental#1.sentence-5) Conveniently that range does not include 0, so we discover that we must use an unsigned integer type to determine the range of values of the enumeration. (We also rule out an unsigned integer type of negative width as that would have a range of values 0 to -Β½ (inclusive) or smaller, which I think we can reasonably conclude is an empty range despite the parenthetical.)

In any case: if you ever wondered whether a zero-bit signed integer type in C++ can represent only the value 0 or only the value -1, now you know: no, it can represent only the value -Β½. Truly a marvelous compromise.

Follow me for more brilliant insights like this one :)

[dcl.enum]

@zygoloid
I disagree with details regarding the negative width signed integer types.
The limits of the representable values of a two's complement integer n bits wide are -(2^(n-1)) and 2^(n-1)-1, so a signed integer -1 bits wide has limits on representable values of -0.25 and -0.75, and such a type can only represent one half of a distinct value.
I agree that such a data type seems to be of rather dubious utility. But just imagine how many of them you can store, before you run out of memory!
@zygoloid
Suppose you have 1 KiB of memory. You ordinarily can use it to store no more than 1024 values of a std::int8_t.
Supposing we have a new data type, std::intnegative8_t, we can e.g. store 1024 of those in our memory, along with 2048 values of type std::int8_t. We have doubled how many signed bytes we can store in a fixed size block of memory, at the relatively minor cost of allocating a few additional data items as overhead.