Forward declaring an enum in C++

szevvy picture szevvy · Sep 16, 2008 · Viewed 195.4k times · Source

I'm trying to do something like the following:

enum E;

void Foo(E e);

enum E {A, B, C};

which the compiler rejects. I've had a quick look on Google and the consensus seems to be "you can't do it", but I can't understand why. Can anyone explain?

Clarification 2: I'm doing this as I have private methods in a class that take said enum, and I do not want the enum's values exposed - so, for example, I do not want anyone to know that E is defined as

enum E {
    FUNCTIONALITY_NORMAL, FUNCTIONALITY_RESTRICTED, FUNCTIONALITY_FOR_PROJECT_X
}

as project X is not something I want my users to know about.

So, I wanted to forward declare the enum so I could put the private methods in the header file, declare the enum internally in the cpp, and distribute the built library file and header to people.

As for the compiler - it's GCC.

Answer

KJAWolf picture KJAWolf · Sep 16, 2008

The reason the enum can't be forward declared is that without knowing the values, the compiler can't know the storage required for the enum variable. C++ Compiler's are allowed to specify the actual storage space based on the size necessary to contain all the values specified. If all that is visible is the forward declaration, the translation unit can't know what storage size will have been chosen - it could be a char or an int, or something else.


From Section 7.2.5 of the ISO C++ Standard:

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.

Since the caller to the function must know the sizes of the parameters to correctly setup the call stack, the number of enumerations in an enumeration list must be known before the function prototype.

Update: In C++0X a syntax for foreward declaring enum types has been proposed and accepted. You can see the proposal at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf