visual variable una son que publicas publica programacion locales las globales externas estaticas desventajas automatica c++ static initialization global-variables

una - variables globales c++



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

¿Cuándo se inicializan estas cuatro variables?

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

¿Dónde se almacenan los valores de inicialización como 5 y 4 durante la compilación?

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

En C++ sé que global objetos static y global se construyen antes de la función main . Pero como saben, en C , no existe un initialization procedure este 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?
  • ¿Dónde se almacenan los valores de inicialización como 5 y 4 durante la compilación? ¿Cómo gestionarlos en la inicialización?

EDITAR:
Aclaración de la 2ª pregunta.

  • En mi código, uso 5 para inicializar global_int1 , entonces, ¿cómo puede el compilador asignar 5 a global_int ? Por ejemplo, tal vez el compilador 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 gestionarlos durante la inicialización?", Es realmente vago y yo mismo no sé cómo interpretar todavía. A veces, no es fácil explicar una pregunta. Pasalo por alto ya que no he dominado la pregunta completamente todavía.

Parafraseado de la norma:

Todas las variables que no tienen una duración de almacenamiento dinámico, no tienen una 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ático.

Los objetos estáticos con inicialización dinámica no se crean necesariamente antes de la primera declaración en la función principal. Es una implementación definida en cuanto a si estos objetos se crean antes de la primera declaració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 a inicializar.

Por lo tanto, en su código, global_int1 y static_int1 se inicializan definitivamente antes de la primera declaración principal porque se inicializan de forma estática. Sin embargo, global_int2 y static_int2 se inicializan dinámicamente, por lo que su inicialización se define de acuerdo con la regla que mencioné anteriormente.

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


Por objetos estáticos y globales, supongo que te refieres a objetos con una vida útil estática definida en el ámbito del espacio de nombres. Cuando tales objetos se definen con un alcance local, las reglas son ligeramente diferentes.

Formalmente, C ++ inicializa tales 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 vida útil estática) son el primer cero se inicializa, luego se inicializan los objetos con inicialización estática y, a continuación, 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; Normalmente, la inicialización estática no lo hace. 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 admite (para variables con vida útil estática), todo lo demás es dinámico.

La forma en que el compilador hace esto depende, por supuesto, de la inicialización, pero en los sistemas basados ​​en disco, donde el ejecutable se carga en la memoria desde el disco, los valores para la inicialización estática son parte de la imagen en el disco y son cargados directamente por el sistema 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 tipos `const` también se colocarían 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 ejecutable no contiene ninguna imagen para este segmento, y el sistema simplemente establece todo a `0` antes de comenzar 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 programas existentes, C ++ 11 probablemente no cambie nada, pero agrega constexpr (lo que significa que algunas funciones definidas por el usuario pueden ser inicializaciones estáticas) y subprocesos variables locales, lo que abre una lata de gusanos completamente nueva.


Prefacio: La palabra "estática" tiene un gran número de significados diferentes en C ++. No te confundas.

Todos tus objetos tienen duración de almacenamiento estático . Eso es porque no son ni automáticos ni dinámicos. (Ni el hilo local, aunque el hilo local es un poco como 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 que se ejecute el código real, por lo que esto sucede con los objetos que comienzan con una llamada del constructor, o donde el inicializador es una expresión que solo se puede evaluar en tiempo de ejecución.

  • La inicialización estática es cuando el inicializador se conoce de forma estática y no es necesario ejecutar ningún constructor. (La inicialización estática es una inicialización cero o una inicialización constante ). Este es el caso de sus variables int con inicializador constante, y tiene la garantía de que esas se inician en la fase estática.

  • (Las variables de almacenamiento estático con inicialización dinámica también tienen inicialización cero 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 "ordenamiento" o cualquier otra propiedad dinámica que se refiera a la inicialización estática. Los valores iniciales están codificados en su programa binario, por así decirlo.