On 11/03/19 16:34, Andrii Nakryiko wrote: > The only thing we should consider is that enums can have different > sizes. And enum size is part of enum's forward declaration. So unlike > struct/union fwd, enum's fwd has extra info. I don't think it's > possible to specify in C (enum is always 4 bytes), Not always, see e.g. N1458 §6.7.2.2.4: > 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 enumeration _constants_ have type int (§6.7.2.2.3), but the enum type itself has implementation-defined size, per the above. C doesn't allow to forward-declare enumerators (§6.7.2.3.3), nor even to reference them from the enumerator-list in the declaration, since the enumerator type is incomplete until the closing brace (§6.7.2.2.4). Footnote 128 adds that "An implementation may delay the choice of which integer type until all enumeration constants have been seen." It appears, in any case, that no forward-declaration could be required in BTF, since an enum type's BTF record does not reference other types. With something like enum foo { BAR = sizeof(enum foo *), }; which is not valid C thanks to §6.7.2.3.3 (but many compilers will accept it, e.g. gcc without -pedantic), the BTF record would read kind=enum name_off=&"foo" vlen=1 name_off=&"BAR" val=8 (assuming 64-bit) which does not require any forward-declaring. I don't know about the C++ situation, though. -Ed PS: It's not really clear to me what the rationale for §6.7.2.3.3 is, since all the problems with incomplete enum types also arise with other incomplete types; why 'enum foo *' can't be treated like 'struct quux *' I don't know. But this isn't comp.std.c...