There's some dissent since this got bumped (sort of), so here's some relevant bits from the standard. Research shows that the standard doesn't really define forward declaration, nor does it explicitly state that enums can or can't be forward declared.
First, from dcl.enum, section 7.2:
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.
So the underlying type of an enum is implementation-defined, with one minor restriction.
Next we flip to the section on "incomplete types" (3.9), which is about as close as we come to any standard on forward declarations:
A class that has been declared but not defined, or an array of unknown size or of
incomplete element type, is an incompletely-defined object type.
A class type (such as "class X") might be incomplete at one point in a translation
unit and complete later on; the type "class X" is the same type at both points. The
declared type of an array object might be an array of incomplete class type and
therefore incomplete; if the class type is completed later on in the translation unit,
the array type becomes complete; the array type at those two points is the same type.
The declared type of an array object might be an array of unknown size and therefore be
incomplete at one point in a translation unit and complete later on; the array types at
those two points ("array of unknown bound of T" and "array of N T") are different
types. The type of a pointer to array of unknown size, or of a type defined by a typedef
declaration to be an array of unknown size, cannot be completed.
So there, the standard pretty much laid out the types that can be forward declared. Enum wasn't there, so compiler authors generally regard forward declaring as disallowed by the standard due to the variable size of its underlying type.
It makes sense, too. Enums are usually referenced in by-value situations, and the compiler would indeed need to know the storage size in those situations. Since the storage size is implementation defined, many compilers may just choose to use 32 bit values for the underlying type of every enum, at which point it becomes possible to forward declare them. An interesting experiment might be to try forward declaring an enum in visual studio, then forcing it to use an underlying type greater than sizeof(int) as explained above to see what happens.