This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2026-03-08
(From submission #843.)
When a variable has an incomplete array type and a braceed initializer, the complete array type can be determined by instantiating a definition of the variable; see 13.9.2 [temp.inst] paragraph 4 and 13.9.2 [temp.inst] paragraph 7. The level of tracking differs between implementations.
// Case 1: Clang rejects because the type of `*p` changes // between redeclarations; Clang seems to be incorrect: // The array bound affects the semantics of the program. template<typename T> struct X { static inline int arr[] = {1, 2, 3}; }; // Clang does not instantiate a definition here. extern decltype(X<int>::arr) *p; // Clang does instantiate a definition here. int n = sizeof(X<int>::arr); decltype(X<int>::arr) *p; // Case 2: GCC, EDG, MSVC reject because they instantiate a definition // of `X<int>::arr` even though it's not odr-used and doesn't appear to // affect the semantics of the program. template<typename T> struct X { static inline int arr[] = {1, 2, T::error}; }; // The array bound here doesn't matter; array-to-pointer decay doesn't // care about it. decltype(+X<int>::arr) r;
Possible resolution:
Add a new paragraph after 13.9.2 [temp.inst] paragraph 8 as follows:
The existence of a definition of a variable or function is considered to affect the semantics of the program if the variable or function is needed for constant evaluation by an expression (7.7 [expr.const]), even if constant evaluation of the expression is not required or if constant expression evaluation does not use the definition. [ Example: ... ]Similarly, the existence of a definition of a variable or function is considered to affect the semantics of the program in which an expression E appears if the instantiation changes the type of E, even if the variable or function is not odr-used (6.3 [basic.def.odr]). [ Example:
template<typename T> struct X { static inline int arr[] = {1, 2, T::error}; }; decltype(+X<int>::arr) r; // error: definition of X<int>::arr is instantiated, because its type changes from "array of unknown bound" to "array of 3 int"-- end example ]