Forcing enum to be of unsigned long type

In C++11 and higher, you can explicitly mention what type you want:

enum MyEnumeration: unsigned long {
   /* ... values go here ... */
};

This will allow you to explicitly control the underlying type.

In C++03, there is no way to force an enumerated type to have any particular underlying implementation. Quoth the C++03 spec, §7.2/5:

The underlying type of an enumeration is an integral type that can represent all the enumerator values defined in the enumeration. It is implementation-defined which integral type is used as the underlying type for an enumeration except that the underlying type shall not be 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. The value of sizeof() applied to an enumeration type, an object of enumeration type, or an enumerator, is the value of sizeof() applied to the underlying type.

This is a pretty lax condition and says that not only can you not necessarily know the type, but because it's implementation-defined there's no guarantee that it even corresponds to one of the primitive types at all.


This can be achieved depending on your compiler. It doesn't work with windows MSVS, but I tested it and it worked with the following versions of the gcc/g++ (plus embedded cpp) compiler:

  • mipsel-openwrt-linux-uclibc-gcc.bin (OpenWrt/Linaro GCC 4.8-2014.04 r47072) 4.8.3
  • g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
  • gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
  • avr-g++.exe (AVR_8_bit_GNU_Toolchain_3.5.4_1709) 4.9.2

By defining one of your enumerations to a value that would be represented in a long value, in some compilers it forced it to that size. The below code generally outputs:

8
4
4

Source:

#include <iostream>
using namespace std;

typedef enum
{
        ENUM_11,
        ENUM_12,

        enum1_force_long = 0x1122334455667788
} LongEnum1_t;

typedef enum
{
        ENUM_21,
        ENUM_22,

        enum2_force_long = 0x11223344
} LongEnum2_t;

typedef enum
{
        ENUM_31,
        ENUM_32,

        enum3_force_long = 0x1122
} LongEnum3_t;

LongEnum1_t enum1;
LongEnum2_t enum2;
LongEnum3_t enum3;
int main(void)
{
        cout << sizeof(enum1) << endl;
        cout << sizeof(enum2) << endl;
        cout << sizeof(enum3) << endl;

        return 0;
}

Tags:

C++

Types

Enums