static
variables are fully initialized before any function in that same translation unit (cpp file more or less) is executed. They are not guaranteed to be initialized before main
is called if main
is in a different translation unit. inline
functions are duplicated, where each translation unit has it's own copy. That means that inline functions in different translation units than the static
variable might attempt to read/write to that variable before it is properly initialized, resulting in undefined behavior. (The rules are very complicated, but that's what I recall)
§ 3.6.2/4 It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first odr-use (3.2) of any function or variable defined in the same translation unit as the variable to be initialized.
and
§ 3.2/3 An inline function shall be defined in every translation unit in which it is odr-used.
inline functions are not really any more dangerous than non-inline functions as far as I know. Any function accessing a static in a different TU is risky, and since inline
just happens to put functions in every TU, most of them aren't safe. One workaround is to use the "construct on first use idiom".
Implicit template specializations are complicated, but for completeness:
§ 14.7.1/3 [temp.inst] the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.
So static members of template classes are always initialized before use.
All of the above is subject to the the static initialization order fiasco), which the aformentioned "construct on first use idom" solves.