nieodroczona inicjalizacja elementu statycznego dla szablonów w gcc?

Czy gcc ma jakiekolwiek gwarancje dotyczące czasu inicjowania statycznych elementów, szczególnie w odniesieniu do klas szablonów?

Chcę wiedzieć, czy mogę uzyskać twardą gwarancję, że statyczni członkowie (PWrap_T<T>::p_s) zostanie zainicjowany wcześniejmain(), gdy klasy są tworzone w wielu jednostkach kompilacji. Próba ręcznego dotknięcia symbolu z każdej jednostki kompilacji na początku głównego nie jest praktyczna, ale nie jest dla mnie jasne, czy cokolwiek innego zadziała.

Przetestowałem takie metodybar() w różnych jednostkach izawsze osiągnąłem pożądany rezultat, ale muszę wiedzieć, kiedy / jeśli kiedykolwiek gcc wyrwie dywanik i czy będzie to możliwe.

Ponadto, czy wszystkie statyczne elementy z DSO zostaną zainicjowane przed zakończeniem ładowania biblioteki?

#include <iostream>
#include <deque>

struct P;
inline std::deque<P *> &ps() { static std::deque<P *> d; return d; }
void dump();

struct P {
  P(int id, char const *i) : id_(id), inf_(i) { ps().push_back(this); }
  void doStuff() { std::cout << id_ << " (" << inf_ << ")" << std::endl; }
  int  const        id_;
  char const *const inf_;
};

template <class T>
struct PWrap_T { static P p_s; };

// *** Can I guarantee this is done before main()? ***
template <class T>
P PWrap_T<T>::p_s(T::id(), T::desc());

#define PP(ID, DESC, NAME) /* semicolon must follow! */  \
struct ppdef_##NAME  {                                   \
  constexpr static int         id()   { return ID; }     \
  constexpr static char const *desc() { return DESC; }   \
};                                                       \
PWrap_T<ppdef_##NAME> const NAME

// In a compilation unit apart from the template/macro header.
void dump() {
  std::cout << "[";
  for (P *pp : ps()) { std::cout << " " << pp->id_ << ":" << pp->inf_; }
  std::cout << " ]" << std::endl;
}

// In some compilation unit.
void bar(int cnt) {
  for (int i = 0; i < cnt; ++i) {
    PP(2, "description", pp);
    pp.p_s.doStuff();
  }
}

int main() {
  dump();
  PP(3, "another", pp2);
  bar(5);
  pp2.p_s.doStuff();
}

(C ++ 11 §3.6.2 / 4 - [basic.start.init] :)

Jest definiowane przez implementację, czy dynamiczna inicjalizacja zmiennej nielokalnej o statycznym czasie przechowywania jest wykonywana przed pierwszą instrukcją main.Jeśli inicjalizacja zostanie odroczona do pewnego punktu w czasie po pierwszym wyrażeniu głównego, nastąpi przed pierwszym użyciem (3.2) dowolnej funkcji lub zmiennej zdefiniowanej w tej samej jednostce translacji, co zmienna, która ma zostać zainicjowana.

... Zmienna nielokalna ze statycznym czasem przechowywania mająca inicjalizację z efektami ubocznymi musi zostać zainicjowana, nawet jeśli nie jest używana (3.2, 3.7.1).

Również próbuję__attribute__ ((init_priority(int))) lub__attribute__ ((constructor)) dla inicjalizacji członka szablonuwarning: attributes after parenthesized initializer ignoredi nie znam żadnych innych sztuczek dotyczących inicjalizacji statycznej.

Z góry dziękuję każdemu, kto może dać mi odpowiedź na ten temat!

questionAnswers(2)

yourAnswerToTheQuestion