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 */