4

What is the type of enumeration constant, when it is used outside unscoped enum definition?

Consider following code:

#include <iostream>

enum modes
{
    begin = 0,
    end = 1
};

int main()
{
    std::cout << std::boolalpha
        << std::is_same<unsigned int, typename std::underlying_type<modes>::type>::value
        << std::endl;
    std::cout << sizeof(modes) << std::endl;
    std::cout << (-100 + end) << std::endl;
}

This yields on my machine:

true
4
-99

Now, if I only change the value of some other enumerator, begin to 2147483648, then my output becomes:

true
4
4294967197

Apparently, It means, that type of end has changed from int to unsigned int, even underlying type of modes is still the same (i.e. unsigned int).

Are there some special rules for integral promotions regarding enums?

Grzegorz Szpetkowski
  • 36,988
  • 6
  • 90
  • 137

2 Answers2

8

From the C++ Standard (7.2 Enumeration declarations)

  1. ...Following the closing brace of an enum-specifier, each enumerator has the type of its enumeration....

And (4.5 Integral promotions)

3 A prvalue of an unscoped enumeration type whose underlying type is not fixed (7.2) can be converted to a prvalue of the first of the following types that can represent all the values of the enumeration (i.e., the values in the range bmin to bmax as described in 7.2): int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int. If none of the types in that list can represent all the values of the enumeration, a prvalue of an unscoped enumeration type can be converted to a prvalue of the extended integer type with lowest integer conversion rank (4.13) greater than the rank of long long in which all the values of the enumeration can be represented. If there are two such extended types, the signed one is chosen.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 1
    "can be converted to a prvalue of the first of the following types that can represent _all the values_ of the enumeration". That is precisely, what I was looking for. Thank you. – Grzegorz Szpetkowski Jul 13 '17 at 21:48
2

What is the type of enumeration constant, when it is used outside unscoped enum definition?

It's the enumeration type, of course. The type of begin is modes. If it had an integral type, your question regarding integral promotions of enums wouldn't make sense.

Are there some special rules for integral promotions with enums?

Not really. You're thinking about integral promotions of the enum's underlying type, but that's something different. For the enum type itself, you need to think about the range of valid values of the enum type, which can be smaller than the range of valid values of the enum's underlying type. Can int can represent all valid values? If so, you get an int out of it.