Description
Quoth C23 draft N3096 in 6.2.1p7 (I haven’t seen the more recent but paywalled N3149):
Structure, union, and enumeration tags have scope that begins just after the appearance of the tag in a type specifier that declares the tag.
In Clang trunk with -std=c23
as well as Clang 16.0.6 with -std=c2x
, on the other hand, I can refer to the enclosing scope’s definition of the tag being declared inside the enum-type-specifier, even though I wouldn’t have been able to do that later inside the enumerator-list:
struct foo { int x; };
void bar(void) { enum foo : typeof(((struct foo *)0)->x); }
// void baz(void) { enum foo { A = sizeof(((struct foo *)0)->x) }; }
// ^^^ error: use of 'foo' with tag type that does not match previous declaration
So this looks to be wrong as far as C23 is concerned. Replacing typeof
by decltype
, I also see this being accepted in C++ mode with -std=c++11
, c++14
, c++17
and c++20
. I don’t know if that’s correct for C++, but I would be surprised if so, because it’s certainly inconsistent with how the typical instance of the CRTP works.
See also #57836 re this feature in C generally.