Section 16.4 of C++ FAQs (2nd Edition) (Paperback) by Marshall P. Cline, Greg Lomow says that inline functions cannot access static data members safely because the function could be called before the static data member is initialized.
I fail to see why this applies to inline functions and not just any functions in other translation units which call a static data member in another translation unit? I fail to see what part "inline" plays in this disaster?
Static inline functions are simple. Either a function defined with the inline function specifier is inlined at a reference, or a call is made to the actual function. The compiler can choose which to do at each reference. The compiler decides if it is profitable to inline at -xO3 and above.
static inline functions indeed don't have much value. So static inline is simply a static function, which automatically satisfies ODR and inline is redundant for ODR purpose. However when we talk about member methods ( class scope), the static inline function does have the value.
5) Inline functions may not be useful for many embedded systems. Because in embedded systems code size is more important than speed. 6) Inline functions might cause thrashing because inlining might increase size of the binary executable file. Thrashing in memory causes performance of computer to degrade.
To resolve this problem use “static” before inline. Using static keyword forces the compiler to consider this inline function in the linker, and hence the program compiles and run successfully.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With