I am observing the following behavior under Visual Studio 2013 (Debug/Win32 compilation). Consider the following c++ code:
#include <iostream>
#include <climits>
int main(int argc, char *argv[])
{
enum { V = (unsigned long long)ULLONG_MAX } E;
std::cout << sizeof E << std::endl;
enum : unsigned long long { W = (unsigned long long)ULLONG_MAX } F;
std::cout << sizeof F << std::endl;
return 0;
}
After compilation this leads to:
$ ./enum.exe
4
8
If I understand the c++ standard correctly (Standard C++ 7.2/5), this is an invalid c++ behavior. In this case, I should not be required to define the underlying type explicitly, since the value of an enumerator cannot fit in an int
or unsigned int
.
So:
Update: as suggested I reported a problem at:
Each enum type has a corresponding integral type called the underlying type of the enum type. This underlying type shall be able to represent all the enumerator values defined in the enumeration. If the enum_base is present, it explicitly declares the underlying type.
In an unscoped enum, the scope is the surrounding scope; in a scoped enum, the scope is the enum-list itself. In a scoped enum, the list may be empty, which in effect defines a new integral type. By using this keyword in the declaration, you specify the enum is scoped, and an identifier must be provided.
For an enumeration whose underlying type is not fixed, the underlying type is an integral type that can represent all the enumerator values defined in the enumeration. If no integral type can represent all the enumerator values, the enumeration is ill-formed.
An enumerated type is a type whose legal values consist of a fixed set of constants. Common examples include compass directions, which take the values North, South, East and West and days of the week, which take the values Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, and Saturday.
' enumeration ': a forward declaration of an unscoped enumeration must have an underlying type (int assumed) A forward declaration of an unscoped enumeration was found without a specifier for the underlying type. By default, Visual C++ assumes int is the underlying type for an enumeration.
An untyped enum now is defined as being at least the width of int (and wider if larger values are needed). However, given a typed enum defined as follows: An enumeration of type name has an underlying type of type. For example, enum : char defines an enum the same width as char instead of int. enum class name : type { value = 0, // ... };
enum struct|class name : type { enumerator = constexpr , enumerator = constexpr , ... } Each enumerator becomes a named constant of the enumeration's type (that is, name ), which is contained within the scope of the enumeration, and can be accessed using scope resolution operator.
There are two distinct kinds of enumerations: unscoped enumeration (declared with the enum-key enum) and scoped enumeration (declared with the enum-key enum class or enum struct). Contents 1 Unscoped enumeration
The reference says the following (important parts bolded):
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).
and
Values of unscoped enumeration type are implicitly-convertible to integral types. If the underlying type is not fixed, the value is convertible to the first type from the following list able to hold their entire value range: int, unsigned int, long, unsigned long, long long, or unsigned long long. If the underlying type is fixed, the values can be converted to their promoted underlying type.
Taken together, it is clear that it is a bug with msvc (probably introduced at some point). What makes matters worse is that it is sort of silent about this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With