Oooch right, incomplete enum is a compiler extension like gcc Incomplete-Enums. The rest of the answer assumes that "incomlpete enum" obeys the same rules as incomplete structures and unions.
Are an incomplete enum and a complete enum compatible types?
Yes (if they are named the same).
Does it mean both types are compatible?
Yes. From the cppreference you linked to:
The types T and U are compatible, if
- they are the same type (same name or aliases introduced by a typedef)
Ie. ET is an alias to enum E in both units - ET is compatible in both units. And later:
- they are both structure/union/enumeration types, and
- (C99)if one is declared with a tag, the other must also be declared with the same tag.
- if both are completed types, blabla
In both enum E has the same tag - E - so they are also compatible. And enum E in second TU is not complete, so the additional points do not apply here.
Let's also mention the original from C11 6.2.7 Compatible type and composite type:
- Two types have compatible type if their types are the same.
Additional rules for determining whether two types are compatible are described in 6.7.2 for type specifiers, in 6.7.3 for type qualifiers, and in 6.7.6 for declarators.
Moreover, two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements: If one is declared with a tag, the other shall be declared with the same tag.
If both are completed anywhere within their respective translation units, then
the following additional requirements apply:
there shall be a one-to-one correspondence between their members such that each pair of corresponding members are declared with compatible types;
if one member of the pair is declared with an alignment specifier, the other is declared with an equivalent alignment specifier;
and if one member of the pair is declared with a name, the other is declared with the same name.
For two structures, corresponding members shall be declared in the same order. For two structures or unions, corresponding bit-fields shall have the same widths.
For two enumerations, corresponding members shall have the same values.
What should I understand by the following sentence?
one is an enumerated type and the other is that enumeration's underlying type
Each enum has an "underlying type" - it's not really an enum as a type, it's actually an int or a char or another implementation-defined type. Let's quote C11 6.7.2.2 Enumeration specifiers:
- Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration. The enumerated type is incomplete until immediately after the } that terminates the list of enumerator declarations, and complete thereafter.
The first sentence is rather explicit. This "real type" compiler chooses is dependent - most of the time it's just an unsigned int or int. See your compiler documentation, like gcc implementation define behavior 4.9 Structures, Unions, Enumerations, and Bit-Fields:
The integer type compatible with each enumerated type (C90 6.5.2.2,
C99 and C11 6.7.2.2).
Normally, the type is unsigned int if there are no negative values in
the enumeration, otherwise int. If -fshort-enums is specified, then if
there are negative values it is the first of signed char, short and
int that can represent all the values, otherwise it is the first of
unsigned char, unsigned short and unsigned int that can represent all
the values.
On some targets, -fshort-enums is the default; this is determined by the ABI.
That point one is an enumerated type and the other is that enumeration's underlying type is about that unsigned int and enum E may be compatible types, so you might just as well use an unsigned int.