I want to fully understand how a C++ compiler deals with an enum exceeding the largest possible number, i.e., containing -1 and UINT64_MAX the at the same time, i.e.
enum A {
X = -1,
Y = UINT64_MAX
};
First I thought that a compiler won't accept this code. Actually it doesn't compile when enumis replaced by enum class, but the above example compiles. According to the standard we have for the underlying type:
Declares an unscoped enumeration type whose underlying type is not fixed (in this case, the underlying type is an implementation-defined integral type that can represent all enumerator values; this type is not larger than int unless the value of an enumerator cannot fit in an int or unsigned int. If the enumerator-list is empty, the underlying type is as if the enumeration had a single enumerator with value 0). (https://en.cppreference.com/w/cpp/language/enum)
But what means this for my example?
I wrote a small sample program to find out what happens:
#include <iostream>
#include <cstdint>
enum A {
X = -1,
XX = -1,
Y = UINT64_MAX
};
int main()
{
std::cout << "X unsigned: " << (uint64_t)(X) << ", signed: " << (int64_t)(X) << std::endl;
std::cout << "Y unsigned: " << (uint64_t)(Y) << ", signed: " << (int64_t)(Y) << std::endl;
std::cout << "(X == XX) == " << (X == XX) << std::endl;
std::cout << "(X == Y) == " << (X == Y) << std::endl;
}
The output is:
X unsigned: 18446744073709551615, signed: -1
Y unsigned: 18446744073709551615, signed: -1
(X == XX) == 1
(X == Y) == 0
Now I am quite confused. Obviously, X and Y represent the same number, but they are still distinguishable, i.e., the comparison X == Y is false (but X=XX is actually true). What happens here?
I know, the better way is not use the old enum, but the new enum class.
But still enum is widely used and I want to understand what happens here.