Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must an enumeration's size be provided when it is forward declared?

Tags:

I just can't see why the size of the enumeration is relevant for the compiler while the size of the class is not.

My code example:

class A;
enum E;   // must be enum E : int; in order to compile 

void f(const A & param);
void f(const E & param);

I'm talking here of standard C++ compilers. I know that MSVC let it compile and works fine. So the question is:

Why this has not been standardized?

like image 766
nyarlathotep108 Avatar asked Mar 13 '15 14:03

nyarlathotep108


People also ask

Why do you use forward declaration?

A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier. In the case of functions, this allows us to tell the compiler about the existence of a function before we define the function's body.

Can enums be forward declared?

Because enum definitions cannot reference one another, and no enum definition can cross-reference another type, the forward declaration of an enumeration type is never necessary.


1 Answers

This has been standardized, proposal 2764: Forward declaration of enumerations (rev. 3) allowed the forward declaration of enums if you specify the underlying type, whereas before this was not possible.

The main reason is that when the underlying type is not specified the size is implementation defined and can depend on the enumerator values. From the draft C++11 standard section 7.2 [dcl.enum]:

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. It is implementation-defined which integral type is used as the underlying type 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.

When passing by value it makes sense that not knowing the underlying type is an issue, but why is it an issue when it is a pointer or reference? This matters since apparently on some architectures, char* and int* can have different sizes as mentioned in this comp.lang.c++ discussion: GCC and forward declaration of enum:

[...] While on most architectures it may not be an issue, on some architectures the pointer will have a different size, in case it is a char pointer. So finally our imaginary compiler would have no idea what to put there to get a ColorsEnum*[...]

We have the following stackoverflow answer for reference which describes the case where char* can be larger than int*, which backs up the assertion in the discussion above.

Some more details on the possible sizes of pointers it looks like char * and void * are the two main exceptions here and so other object pointers should not have the same issues. So it seems like this case ends up being unique to enums.

like image 162
Shafik Yaghmour Avatar answered Dec 08 '22 01:12

Shafik Yaghmour