The initializer "sizeof (T)" of the built-in static auto ... Is instance creation required?

What happens if the type of an expression is independent, but we use it to initialize a static automatic variable? GCC and Clang differ in behavior

template<typename T> struct A { static inline auto x = sizeof(T{}.f); }; A<int> a; 

GCC does not cause an error. But Klang thinks this is not true, because he creates an instance of "sizeof". GCC seems to skip this step because sizeof(T{}.f) always has type size_t (type independent), so it already knows type x without instantiating. Both compilers reject the program accordingly if we refer to x , for example, to (void) ax; .

Does type x need to be allowed at all? From C ++ 14 up, the language allows you to store things (for example, functions) with a placeholder type and do a delayed instantiation to find out about the actual return type later, if I remember correctly. Does this need to be applied to x , so keeping x with a placeholder type until we refer to ax ?

Which compiler is correct according to standards?


EDIT

Someone asked

uhm, shouldnt 'is it 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, to find out the type of x , you need to know the type of initializer. Clang seems to instantiate the initializer to get the type. But does the GCC apparently not look? I would like to understand what is happening.

+5
source share
1 answer

From [temp.inst] / 3 :

If a class template member or member template is not explicitly created or is not explicitly specialized, the specialization of this element is implicitly created when the specialization is referenced in a context that requires a member definition; in particular, initialization (and any side effects associated with it) of a static data member does not occur if the static data member itself is not used in such a way that a definition of the static data member is required.

Just write A<int> a; means that noes does not use A<int>::x so that its definition exists, so its initialization should not occur. gcc is correct.

+2
source

Source: https://habr.com/ru/post/1273233/


All Articles