What should happen if an expression's type is not dependent, but we use it to initialize a static auto variable? GCC and Clang differ in their behavior
template<typename T>
struct A {
static inline auto x = sizeof(T{}.f);
};
A<int> a;
GCC doesn't raise an error. But Clang thinks that this is invalid because it instantiates the operand of "sizeof". GCC appears to skip that step because sizeof(T{}.f) always has type size_t (not type dependent), so it already knows type of x without instantiation. Both compilers conformly reject the program if we refer to x, for example by (void) a.x;.
Does it even have to resolve the type of x at all? With C++14 upwards the language allows keeping things (like functions) with a "placeholder type" and doing delayed instantiation to find out about the actual return type later on, if I remember correctly. Does it have to apply this to x aswell, so keeping x with a placeholder type till we refer to a.x?
What compiler is correct according to the Standards?
EDIT
Someone asked
uhm, shouldnt' this be equivalent to this ?
template<typename T> struct A { static const std::size_t x; }; template<typename T> inline constexpr std::size_t A<T>::x = sizeof(T{}.f);
The difference, and what concerns me in my question, is that the static data member in my question is auto. Therefore, in order to know the type of x, you need to know the type of the initializer. Clang appears to instantiate the initializer eagerly in order to get the type. But GCC doesn't, apparently? I would like to understand what's going on.