2011-12-02 6 views
12

Las variables globales se inicializan para aparecer en el módulo de traducción y el orden relativo de inicialización de variables en diferentes módulos de traducción en no especificado (denominado "fiasco de orden de inicialización estática").¿Los espacios de nombres afectan el orden de inicialización en C++?

¿Los espacios de nombres tienen alguna influencia sobre eso? Por ejemplo, si tengo este código:

//first.cpp 
int first; 
int second; 

¿tendrá alguna diferencia en el orden de inicialización en comparación con este código:

//second.cpp 
namespace { 
int first; 
} 
int second; 

¿Hay casos en los que poner un objeto global en un espacio de nombres afecta orden de inicialización?

+1

Tenga en cuenta que el estándar C++ define que los nombres globales son solo aquellos que aparecen en el ámbito global ([basic.scope.namespace]/3). Por lo que respecta a C++, en second.cpp 'first' no es global. Obviamente para todos los propósitos prácticos de hacer con "globales" y especialmente "globales" mutables siendo un PITA para trabajar, en todos los lenguajes de programación, es un "global". –

Respuesta

11

3.6 Otras variables no locales con duración de almacenamiento estática han ordenado la inicialización. Las variables con inicialización ordenada definida dentro de una sola unidad de traducción se inicializarán en el orden de sus definiciones en la unidad de traducción.

Los espacios de nombre no tienen ningún efecto sobre esto, no se mencionan en la sección.

¿Qué efecto tiene el orden en las diferentes unidades de traducción? Si necesita definir el orden entre ellos, use una extensión como el atributo constructor de GCC.

+0

En lugar de usar extensiones para controlar el pedido, recomendaría evitar la dependencia por completo. –

+0

@ DavidRodríguez-dribeas Aún mejor, evite el almacenamiento estático. – Pubby

5

Bueno, las "variables globales se inicializan para aparecer en el módulo de traducción" es definitiva. No deja espacio para nada más, como espacios de nombres, para afectar el orden.

En realidad, "Las variables globales se inicializan en orden ..." es una cita imprecisa de la norma, ya que es formalmente incorrecta. Las palabras exactas de C++ estándar, ISO/IEC 14882: 2003, 3.6.2 párrafo 1 es:

objetos con una duración de almacenamiento estático se define en el ámbito del espacio de nombres en la misma unidad de traducción y dinámicamente inicializado se inicializan en el orden en que aparece su definición en la unidad de traducción.

Así que en lugar de "global" que dice "con el almacenamiento estático", es decir todas las variables no locales si son miembros del espacio de nombres global, o miembros de la clase y si son declarados static o no.

También agrega "y se inicializa dinámicamente". Las variables con constructores triviales e inicializador constante siempre se inicializan primero (simplemente cargando sus valores desde el binario) y luego de que todos los inicializadores no constantes se evalúan y los constructores no triviales se ejecutan en ese orden. Esto es importante, por lo que puede, por ejemplo, crear de forma confiable una lista vinculada en esos constructores; si su cabecera es un puntero simple, ya está inicializado, por lo que puede trabajar con ella de forma segura.

+0

+1 para el énfasis: 'the" Las variables globales se inicializan para aparecer en el módulo de traducción "es definido'. ¡Fin de la historia! – Nawaz

+0

La oración "definitiva" como se indica solamente.afecta las variables globales.cosas en espacios de nombres definidos por el usuario no son globales –

+0

@ JohannesSchaub-litb: Sí, son globales. Me estás obligando a buscar la redacción exacta en la especificación. Ok, aquí viene ... (ver edición). –

Cuestiones relacionadas