C ++: estática en la inicialización dependiente de la variable miembro estático con int vs struct

Dada una variable miembro estática que se inicializa a partir de una variable miembro estática deotra clase, el no literalstruct ii a veces se inicializa por defecto en0 o a333. Esto depende del orden de compilación o enlace.Pseudocódigo demostrar:

class StaticClass: // file 'ONE.cpp/.hpp'
    static int i = 2
    static struct ii { int a = 333 }

class ABC: // file 'abc.cpp'
    static int abc_i = StaticClass::i   // always 2
    static struct abc_ii = StaticClass::ii // sometimes 0, sometimes 333

Vocacióng++ -std=c++11 abc.cpp ONE.cpp && ./a.out resultados eni = 2 / ii = 0 (gcc 4.8.1, lo mismo con clang ++ 3.7;-Wall -Wextra Nunca te quejes).

Pero llamandog++ -std=c++11 ONE.cpp abc.cpp && ./a.out resultados eni = 2 / ii = 333 !

Lo mismo sucede conONE.o abc.o vsabc.o ONE.o y también al concatenar los archivos de una forma u otra:

cat ONE.cpp abc.cpp > X.cpp && g++ X.cpp && ./a.out vscat abc.cpp ONE.cpp > Y.cpp && g++ Y.cpp && ./a.out

Eliminando incluye y moviendo el código en el archivo único, la inicialización predeterminada a 0 ocurre cuando este orden está presente:

const OneI ABC::def_ii = StaticClass::ii; const OneI StaticClass::ii = OneI{333};

y el de 333 con este pedido:

const OneI StaticClass::ii = OneI{333}; const OneI ABC::def_ii = StaticClass::ii;

¿Por qué sucede esto con dos unidades de compilación separadas? ¿Se puede evitar esto de alguna manera haciendo cumplir el último pedido todo el tiempo? Está utilizando un puntero estático enABC aStaticClass::ii seguro (preferiría no hacerlo, sin embargo)?

Código completo de C ++:

/* File: abc.cpp */

#include <iostream>
#include "ONE.hpp"

struct ABC {
  ABC();

  static const int def_i;
  static const OneI def_ii;
  void arg_i(const int &x) { std::cout << "i = " << x << " ";};
  void arg_ii(const OneI &x) { std::cout << "/ ii = " << x.a << " ";};

};

ABC::ABC() {
  arg_i(def_i);
  arg_ii(def_ii);
}

const int ABC::def_i = StaticClass::i;
const OneI ABC::def_ii = StaticClass::ii;

int main() {
  ABC a;
  std::cout << '\n';
}
/* End: abc.cpp */
/* File: ONE.cpp */

#include <iostream>

#include "ONE.hpp"

const int StaticClass::i = 2;
const OneI StaticClass::ii = OneI{333};

/* End: ONE.cpp */
/* File: ONE.hpp */

#include <iostream>

#ifndef One
#define One

struct OneI {
  OneI(int a_) : a(a_) { }
  int a;
};

struct StaticClass {
  const static int i;
  const static OneI ii;
};

#endif // One header guard

/* End: ONE.hpp */

Respuestas a la pregunta(1)

Su respuesta a la pregunta