Pregunta

Estoy acostumbrado a pensar en toda la inicialización de variables globales / clase-miembros estáticos como ocurre antes de la primera línea de main (). Sin embargo, recientemente he leído por ahí que la norma permite la inicialización ocurra más tarde para "ayudar con la carga dinámica de módulos." Pude ver que era cierto cuando la vinculación dinámica: Yo no esperaría que un mundial inicializado en una biblioteca que ser inicializado antes de que dlopen'ed la biblioteca. Sin embargo, dentro de una agrupación de forma estática unidos entre sí unidades de traducción (archivos .o directos de mi app) que iba a encontrar este comportamiento muy poco intuitivo. ¿Tiene esto sólo sucede cuando perezosamente dinámica que une o puede suceder en cualquier momento? (O era simplemente lo que he leído mal;?)

¿Fue útil?

Solución

El estándar tiene la siguiente en 3.6.2 / 3:

  

Se define-aplicación si o no la inicialización dinámica (8.5, 9.4, 12.1, 12.6.1) de un objeto de   ámbito de espacio de nombres se hace antes de la primera declaración del principal. Si la inicialización se difiere hasta cierto punto   en el tiempo después de la primera declaración del principal, deberá producirse antes del primer uso de cualquier función o un objeto definido   en la misma unidad de traducción como el objeto a ser inicializado.

Pero O Por supuesto que puedes Nunca oficialmente decir cuando la inicialización se lleva a cabo ya que la inicialización se producirá antes de acceder a la variable! como siguiente:

// t1.cc
#include <iostream>
int i1 = 0;

int main () {
  std::cout << i1 << std::endl

// t2.cc
extern int i1;
int i2 = ++i1;

I puedo conformar que g ++ 4.2.4 al menos aparece para llevar a cabo la inicialización de 'i2' antes principal.

Otros consejos

El problema que se quería resolver con esa regla es la de la carga dinámica. La asignación no se limita a la carga dinámica y formalmente podría ocurrir por otros casos. No sé una aplicación que lo utilizan para nada más que la carga dinámica.

Vamos a repasar un pseudocódigo:

En DLL:

static int ItsDllVar = 1;
int EXPORTED_FUNCTION() { return ItsDllVar; }

En aplicación:

static int AppVar1 = 2;
static int AppVar2 = EXPORTED_FUNCTION() + AppVar1;

Así que de acuerdo a AppVar2 inicialización estática obtiene 1 + 2 = 3

inicialización perezosa aplicable para las variables estáticas locales (independientemente de la DLL)

int f()
{
    static int local_i = 5;//it get's 5 only after visiting f()
    return local_i;
}

Creo que esto es lo que ocurrió en mi caso con g ++ 4.7 y CMake (no estoy seguro si esto es un detalle relevante con respecto a CMake). Tengo un código que registra una función en la fábrica. Se basa en el constructor llamando desde una variable inicializada a nivel mundial.

Cuando este código estaba en el biblioteca enlazado estáticamente la inicialización no sucedió! Ahora se está trabajando bien, cuando lo moví a los ficheros objeto que enlazaban directamente (es decir, que no se combinan en una biblioteca primero).

Por lo tanto, sospecho que estás en lo correcto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top