Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Underlying type of an unscoped enum?

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:

  1. Is this is a well known limitation of Visual Studio 2013 (maybe other versions are affected) ?
  2. Is there a way to force the compiler to use a proper underlying type for a c++98 style enum ? Or am I required to switch to c++11 notation with fixed-type ?

Update: as suggested I reported a problem at:

  • https://developercommunity.visualstudio.com/content/problem/524018/underlying-type-of-an-unscoped-enum.html
like image 623
malat Avatar asked Apr 08 '19 13:04

malat


People also ask

What is the underlying type of an enum?

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.

What is an Unscoped enum 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.

What is underlying type in C?

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.

What are enumeration data types give example?

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.

What is the underlying type of an unscoped enumeration?

' 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.

What is the difference between typed and untyped enums?

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, // ... };

What is the enum struct/class name?

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.

What are the different types of enumerations in C++?

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


1 Answers

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.

like image 142
darune Avatar answered Oct 13 '22 02:10

darune