¿Cuándo se inicializan las variables estáticas y globales?

En C++ sé que global objetos static y global se construyen antes de la función main . Pero como usted sabe, en C , no existe tal initialization procedure tipo antes de main .

Por ejemplo, en mi código:

 int global_int1 = 5; int global_int2; static int static_int1 = 4; static int static_int2; 
  • ¿Cuándo se inicializan estas cuatro variables?
  • Donde los valores de inicialización como 5 y 4 se almacenan durante la comstackción? ¿Cómo administrarlos cuando se inicializa?

EDITAR:
Aclaración de la 2da pregunta.

  • En mi código, uso 5 para inicializar global_int1 , entonces, ¿cómo puede el comstackdor asignar 5 a global_int ? Por ejemplo, tal vez el comstackdor primero almacene el valor 5 en algún lugar (es decir, una tabla), y obtenga este valor cuando comience la inicialización.
  • En cuanto a “¿Cómo administrarlos cuando se inicializa?”, Es realmente vago y yo mismo todavía no sé cómo interpretarlo. A veces, no es fácil explicar una pregunta. Pasar por alto ya que no he dominado la pregunta por completo todavía.

Con objetos estáticos y globales, supongo que se refiere a objetos con duración estática definida en el ámbito del espacio de nombres. Cuando tales objetos se definen con scope local, las reglas son ligeramente diferentes.

Formalmente, C ++ inicializa dichas variables en tres fases: 1. Inicialización cero 2. Inicialización estática 3. Inicialización dinámica El lenguaje también distingue entre variables que requieren inicialización dinámica y aquellas que requieren inicialización estática: todos los objetos estáticos (objetos con duración estática) son primer cero inicializado, luego se inicializan los objetos con inicialización estática y luego se produce la inicialización dinámica.

Como primera aproximación simple, la inicialización dinámica significa que se debe ejecutar algún código; típicamente, la inicialización estática no. Así:

 extern int f(); int g1 = 42; // static initialization int g2 = f(); // dynamic initialization 

Otra aproximación sería que la inicialización estática es lo que C soporta (para variables con tiempo de vida estático), todo lo demás dynamic.

La forma en que el comstackdor hace esto depende, por supuesto, de la inicialización, pero en los sistemas basados ​​en disco, donde el ejecutable se carga en la memoria del disco, los valores para la inicialización estática son parte de la imagen en el disco, y el sistema los carga directamente desde el disco. En un sistema Unix clásico, las variables globales se dividirían en tres “segmentos”:

texto:
El código, cargado en un área protegida de escritura. Las variables estáticas con los tipos `const` también se colocarán aquí.
datos:
Variables estáticas con inicializadores estáticos.
Bss:
Variables estáticas sin inicializador (C y C ++) o con inicialización dinámica (C ++). El archivo ejecutable no contiene ninguna imagen para este segmento, y el sistema simplemente lo configura todo en `0 ‘antes de iniciar su código.

Sospecho que muchos sistemas modernos todavía usan algo similar.

EDITAR:

Una observación adicional: lo anterior se refiere a C ++ 03. Para los progtwigs existentes, C ++ 11 probablemente no cambia nada, pero agrega constexpr (lo que significa que algunas funciones definidas por el usuario aún pueden ser inicialización estática) y enlorta variables locales, lo que abre una nueva lata de gusanos.

Prefacio: la palabra “estática” tiene una gran cantidad de significados diferentes en C ++. No te confundas

Todos sus objetos tienen una duración de almacenamiento estático . Eso es porque no son automáticos ni dynamics. (Ni thread-local, aunque thread-local es un poco estático).

En C ++, los objetos estáticos se inicializan en dos fases: inicialización estática e inicialización dinámica.

  • La inicialización dinámica requiere el código real para ejecutarse, por lo que esto sucede para los objetos que comienzan con una llamada de constructor, o donde el inicializador es una expresión que solo se puede evaluar en tiempo de ejecución.

  • La inicialización estática se produce cuando el inicializador se conoce estáticamente y no se necesita ejecutar ningún constructor. (La inicialización estática es inicialización cero o inicialización constante ). Este es el caso de las variables int con inicializador constante, y se garantiza que esas se inicializan en la fase estática.

  • (Las variables de almacenamiento estático con inicialización dinámica también se inicializan con cero de forma estática antes de que ocurra cualquier otra cosa).

El punto crucial es que la fase de inicialización estática no se “ejecuta” en absoluto. Los datos están ahí desde el principio. Eso significa que no hay ningún “pedido” o cualquier otra propiedad dinámica que tenga que ver con la inicialización estática. Los valores iniciales están codificados de manera rígida en el progtwig binario, si lo desea.

¿Cuándo se inicializan estas cuatro variables?

Como dices, esto sucede antes del inicio del progtwig, es decir, antes de que comience el main . C no lo especifica más; en C ++, ocurren durante la fase de inicialización estática antes de objetos con constructores o inicializadores más complicados.

Donde los valores de inicialización como 5 y 4 se almacenan durante la comstackción?

Normalmente, los valores distintos de cero se almacenan en un segmento de datos en el archivo de progtwig, mientras que los valores cero están en un segmento bss que solo reserva suficiente memoria para las variables. Cuando se inicia el progtwig, el segmento de datos se carga en la memoria y el segmento bss se pone a cero. (Por supuesto, el estándar de lenguaje no especifica esto, por lo que un comstackdor podría hacer otra cosa, como generar código para inicializar cada variable antes de ejecutar main ).

Parafraseado del estándar:

Todas las variables que no tienen una duración de almacenamiento dinámica, no tienen duración de almacenamiento local de subprocesos y no son locales, tienen una duración de almacenamiento estática. En otras palabras, todos los globales tienen una duración de almacenamiento estática.

Los objetos estáticos con inicialización dinámica no necesariamente se crean antes de la primera instrucción en la función principal. Se define la implementación en cuanto a si estos objetos se crean antes de la primera instrucción en main, o antes del primer uso de cualquier función o variable definida en la misma unidad de traducción que la variable estática que se va a inicializar.

Entonces, en su código, global_int1 y static_int1 definitivamente se inicializan antes de la primera instrucción en main porque están inicializados estáticamente. Sin embargo, global_int2 y static_int2 se inicializan dinámicamente, por lo que su inicialización se define según la regla I mencionada anteriormente.

En cuanto a su segundo punto, no estoy seguro de entender lo que quiere decir. ¿Podrías aclarar?