[cxx-abi-dev] How to handle initialization of static members of class templates.
Rafael Espíndola
rafael.espindola at gmail.com
Thu Oct 9 18:17:00 UTC 2014
Given
---------------------------------------------------------------
struct S {
static const int x;
};
template<typename T> struct U {
static const int k;
};
template<typename T> const int U<T>::k = T::x;
#ifdef TU1
const int S::x = 42;
extern const int *f();
const int *g() { return &U<S>::k; }
int main() {
return *f() + U<S>::k;
}
#endif
#ifdef TU2
const int *f() { return &U<S>::k; }
#endif
------------------------------------------------------
_ZN1UI1SE1kE is a contant in TU1 but not in TU2. When compiling with
gcc this can cause the resulting program to segfault as the
initialization function tries to modify constant memory.
The way this was fixed in clang is to put more things in the
_ZN1UI1SE1kE comdat when compiling TU2. In particular, it puts
* The .init_array section with a pointer to the init function
* The init function itself
* The guard variable
If the linker decides to discard this _ZN1UI1SE1kE, the initialization
code also goes away. If it decides to keep it, the .init_array section
ends up being merged with the other sections with the same name and
everything works.
Cheers,
Rafael
More information about the cxx-abi-dev
mailing list