This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2026-05-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; // Case 3: GCC and clang accept; MSVC rejects because it instantiates a definition // of X<int>::arr even though it's not odr-used and its type is complete. // EDG rejects because it instantiates the definition of arr while instantiating X<int>. template<typename T> struct X { static inline int arr[3] = {1, 2, T::error}; }; // No definition needed, thus the initializer is not instantiated. decltype(+X<int>::arr) r;
Proposed resolution (approved by CWG 2026-05-08):
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 if the instantiation is necessary to determine the type of an expression in the program, 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 to complete its type template<typename T> struct X2 { static inline int arr[3] = {1, 2, T::error}; }; decltype(+X2<int>::arr) r; // OK, type of arr is complete and arr is not odr-used-- end example ]