variable una temporales son qué locales globales entre ejemplo diferencia declarar declaraciones cual como c++ static-initialization

c++ - una - variables globales pdf



¿Cuándo es segura la inicialización de las constantes globales con enlace externo del orden de inicialización estática? (2)

Considere el siguiente ejemplo:

  • tt.h declara una constante global con enlaces externos extern int g_TRAGIC;

  • tt.cpp define g_TRAGIC como sigue const int g_TRAGIC = 0xF001;

  • my.cpp quiere usarlo para definir su propia constante global constante const int g_MAGIC = g_TRAGIC;

Cuando leo el iso-FAQ supongo que esto da como resultado un fiasco de orden de inicialización estática. Sin embargo, las notas iso-FAQ

El fiasco de orden de inicialización estático también puede, en algunos casos, aplicarse a los tipos intrínsecos / incorporados.

¿Qué significa eso en algunos casos? ¿En qué condiciones se guardan y suenan desde SIOF para tipos incorporados / intrínsecos, en particular constantes? ¿O se debe usar Construir en el primer uso del idioma para todas las constantes con enlace externo?

Nota: En el código real no puedo cambiar la definición de g_TRAGIC.


La lectura adicional de iso-FAQ nos da una respuesta.

SIOF sucede si intenta inicializar el tipo incorporado / intrínseco por el valor de retorno de la función constante.

const int g_MAGIC = f(g_TRAGIC);


Los compiladores pueden producir diferentes tipos de código.

Segmento de datos inicializado estático

El compilador emite en una sección de datos un nombre y su valor inicial.

.data dw myData 6

Esto se inicializa en el momento de la compilación y se define de manera segura a lo largo de la vida del programa.

datos construidos

Otra alternativa es que el compilador reserve algo de espacio para la variable y cree un inicializador / constructor para los datos, y luego llame al constructor justo antes de main . Con el destructor (si es necesario) realizado atexit .

class CriticalSection { CRITICAL_SECTION m_myCS; public: CriticalSection() { InitializeCriticalSection( &m_myCS ); } ~CriticalSection() { DeleteCriticalSection( & m_myCS ); } } cs;

conjunto

Algunos datos se pueden realizar en ambas etapas.

struct Data { bool initialized; void *(*pMalloc)( size_t size ); } FixMalloc = { true, MyMalloc };

He visto a los compiladores (VS2013) producir código que se inicializa como verdadero en los datos estáticos, pero crea una función para asignar pMalloc a MyMalloc en tiempo de ejecución. (Esto se debió a que no había una constante conocida para MyMalloc).

método singleton

SomeClass * GetSomeClass() { static SomeClass cls; return &cls; }

Este es un orden definido: cuando se llama, pero requiere que un compilador totalmente C++11 sea ​​seguro para subprocesos.

Resumen

Las garantías son: -

  1. Las estadísticas en la misma unidad de compilación se inicializan de arriba a abajo.
  2. Las estadísticas están inicializadas de un solo hilo.
  3. Los singletons tienen orden de construcción definido. Pero no necesariamente hilo seguro.

Las garantías no son:

  1. Todo un objeto se inicializa al mismo tiempo.
  2. La inicialización estática tiene un tiempo de ejecución de trabajo.

Antes de llamar a main, tanto sus estadísticas como el tiempo de ejecución de C / C ++ son bootstrapping. Los problemas de orden de construcción también ocurren entre su código y el tiempo de ejecución, por lo que puede construir algunos elementos con constructores complejos que dependen de servicios que no pueden estar disponibles.