[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