Authors: Jay Ghiron
Date: 2026-10-23
Submitted against: C23
Status: Open
This issue is about the wording added by N3006 as amended by N3144.
A declaration such that the declaration specifiers contain no type specifier or that is declared with
constexpris said to be underspecified. If such a declaration is not a definition, if it declares no or more than one ordinary identifier, if the declared identifier already has a declaration in the same scope, if the declared entity is not an object, or if anywhere within the sequence of tokens making up the declaration identifiers that are not ordinary are declared, the behavior is implementation-defined.
(C23 6.7.1 "General" paragraph 12.)
Consider the following declarations:
constexpr enum{x}a=0;
auto b=(enum{y})0;
Was it intended that these do not trigger the implementation-defined
behavior? Note that enumerators are ordinary identifiers. In C2Y if
an implementation accepts struct{static_assert(1);}, this question
would also apply to structures with no named members. GCC rejects
these declarations, Clang accepts them though does not reject
definitions of structures or unions either.
An ordinary identifier that has an underspecified definition has scope that starts when the definition is completed; if the same ordinary identifier declares another entity with a scope that encloses the current block, that declaration is hidden as soon as the inner declarator is completed.
(C23 6.2.1 "Scopes of identifiers, type names, and compound literals" paragraph 7.)
Consider the following:
typedef int T,U;
int main(){
constexpr int(*T)(T)=0;
constexpr char U[sizeof(U)]={};
}
Are these declarations valid? That is, does "inner declarator" mean to refer to the declarator inside of the declaration or the innermost declarator therein? Note that an attribute specifier which appertains to the object is part of the innermost declarator, though there are no standard attributes for which this would matter. Both GCC and Clang accept these declarations.