2010-10-15 17 views
6

tengo una biblioteca estática con el siguiente código:Miembro estático fallo objeto de inicialización

h: Archivo de

class Foo 
{ 
public: 
    Foo() 
    { 
     a = 4; 
    } 

    int a; 
}; 


class Bar 
{ 
public: 
    static const Foo foo; 
}; 

CPP:

const Bar::foo = Foo(); 

Mi problema es que Bar :: foo no se inicializa con a = 4 hasta algún tiempo después de main(). Antes de eso a = 0. Estoy intentando acceder a Bar :: foo desde una DLL que enlaza estáticamente a la biblioteca de arriba. Y mi aplicación vincula a esa DLL pero no accede a Bar :: foo directamente. Estoy usando Visual Studio 2008.

¿Alguien sabe lo que podría estar pasando?

Respuesta

7

$ 3.6.2/2- "Variables con duración estática almacenamiento (3.7.1) o de hilos de duración de almacenamiento (3.7.2) serán cero-inicializado (8.5) antes de cualquier otro inicialización toma lugar."

Eso explica por qué se obtiene que el valor de 0

$ 3.6.2/4- "Se define a la ejecución si el inicialización dinámica de un variable no local con almacenamiento estático duración se realiza antes de la primera instrucción de principal. Si la inicialización es diferida a algún punto en el tiempo después de aparece la primera declaración de principal, deberá ocurrir bef o el primer uso de cualquier función o variable definida en la unidad de traducción como la variable a ser inicializada. "

Así que lo que estamos tratando de hacer conduce a un comportamiento no definido como que está intentando acceder a una variable con una duración de almacenamiento estático que aún no se ha inicializado ya que ningún código en el que la unidad de traducción se ha utilizado hasta el momento.

+0

comportamiento definido por la implementación de Microsoft para el escenario descrito es que la inicialización habrá ocurrido antes de que se realice la llamada de 'proceso adjunta' de DllMain(). –

+0

@Michael Burr: Oh Ok. Esa es una buena información. Gracias. – Chubsdad

1

Dónde y cuándo exactamente se accediendo Bar::foo? Si está vinculado estáticamente a la DLL, entonces debería ser inicializado antes del proceso de DllMain() 's 'conectar' se llama.

es usted la creación de un punto de entrada diferente para el DLL que el predeterminado de _DllMainCRTStartup?

+0

No estoy usando _DllMainCRTStartup; el DLL no tiene un punto de entrada per se, es solo un grupo de interfaces de clase abstracta e implementaciones con una función C externa global para crear la instancia de la clase raíz. Se hace de esta manera para ser compatible con binarios. ¿Debo definir un punto de entrada? – Matthew

+0

'_DlMainCRTStartup' es parte de la biblioteca de tiempo de ejecución; la obtendrá de manera predeterminada a menos que haga algo específicamente para anularla. –

+0

@Matthew: ¿cómo se ejecuta el código en la DLL antes de 'main()'? Debe haber algo en 'DllMain()', un punto de entrada DLL alternativo, o algún init estático en su .exe debe estar llamando al DLL. –

1

¿Por qué no define un método estático en la barra que devuelve una referencia a Foo, y en ese método estático, tiene una instancia estática de Foo, de modo que cuando se llama por primera vez (independientemente de dónde), obtendrá ¿Inicializado correctamente?

class Bar 
{ 
    public: 
    static Foo& foo() 
    { 
     static Foo inst; 
     return inst; 
    } 
}; 
1

¿Qué código está notando que Bar::foo aún no se ha inicializado?Si se trata de otro poco de inicialización estática en la DLL entonces usted está probablemente corriendo en estática problema de orden de inicialización C++ 's:

Cuestiones relacionadas