Acerca de "estático" en C, ¿cómo lo implementa el compilador?Acerca de "estático" en C, ¿cómo lo implementa el compilador?
Esta es una pregunta de la entrevista de Bloomberg. Alguna idea ?
Acerca de "estático" en C, ¿cómo lo implementa el compilador?Acerca de "estático" en C, ¿cómo lo implementa el compilador?
Esta es una pregunta de la entrevista de Bloomberg. Alguna idea ?
[[Estoy asumiendo que estamos hablando de static
en el contexto de las variables aquí, porque static
funciones son simplemente una cosa de compilación/enlace en tiempo, sin implicaciones en tiempo de ejecución.]]
En resumen, es específico de la implementación. El compilador es libre de hacer lo que quiera.
Normalmente (pero de ninguna manera exclusivamente), las estáticas se almacenan en las secciones .bss o .data de la imagen ejecutable en ubicaciones fijas. Esto tiene ventajas de rendimiento, ya que se puede acceder con direcciones literales, en lugar de referencias de punteros (como sería el caso para las variables basadas en la pila). Como esto es parte del binario, esto también significa que los valores iniciales se mapean automáticamente en la memoria cuando el ejecutable se carga por primera vez; no se requieren rutinas de inicialización.
... entonces, ¿por qué hicieron esta estúpida pregunta? ... ¿qué respuesta quieren? –
@Andy Leman no es estúpido. para este tipo de preguntas, la respuesta correcta es 1) se puede decir cómo lo hace un compilador específico 2) si no se sabe cómo se implementaría. – Andrey
Quizás estaban refiriendo uno de los otros usos de 'static'. –
variables globales estáticas generalmente se asignarán una dirección fija en el momento de la compilación. Muchos SO proporcionan regiones de memoria que se inicializan con 0, otras que mapean parte de la imagen ejecutable con datos preinicializados, así como áreas totalmente no inicializadas. Dependiendo de si el compilador puede encontrar el contenido inicial correcto de la variable estática en el momento de la compilación, puede seleccionar la región de memoria más apropiada, llamando a cualquier inicialización en tiempo de ejecución más adelante si es necesario. Por ejemplo:
static int x; // needs to be 0 before main() runs
// best way: 0-initialised memory area
static int y = 3; // best way: map/copy area of executable already containing "3"
static int z = time(NULL); // initial value unimportant
// best way: uninitialised memory area
// pre-main() init code
Notas: poner p. Ej. z
en la memoria inicializada en 0 y después no es un derroche significativo, simplemente no es estrictamente necesario. Algunos SO pueden tener áreas separadas para valores de solo lectura/const.
variables locales estáticas con valores iniciales conocidos en tiempo de compilación pueden crearse como por globales. Para los valores inicializados en tiempo de ejecución (solo legales en C++), los compiladores tienden a (¿deben?) Inicializarlos cuando se ingresa el alcance por primera vez. Esto normalmente se coordina al tener un valor booleano de soporte implícito por alcance que contiene variables locales estáticas: cada vez que se ingresa el alcance, se consulta al booleano para ver si las estadísticas deben ser inicializadas. En algunos compiladores, esto realmente se puede hacer de una manera menos eficiente pero segura para subprocesos, de modo que los locales estáticos se puedan usar para instancias de singleton.
EDIT: Teniendo en cuenta el comentario de Lundin (correctamente) hacer valer toda la estática C debe ser inicializado antes de main()
, escribí algo de código para explorar esta:
#include <stdio.h>
#include <time.h>
void f()
{
static int i = time(NULL);
printf("%d\n", i);
}
int main()
{
int i = time(NULL);
printf("%d\n", i);
sleep(2);
f();
}
con el compilador C de GCC, me sale un error de compilación fatal en el local static i
que requiere inicialización en tiempo de ejecución. Compilado como C++ (mi idioma principal), esto es perfectamente legal y se inicializa en el tiempo de ejecución y después de ingresar al main()
, mostrando que esa parte de mi explicación anterior solo es relevante para C++.
Las funciones estáticas están simplemente marcadas en el objeto generado de modo que el vinculador no las tendrá en cuenta al hacer coincidir llamadas no resueltas desde otros objetos.
Para todas las variables estáticas (y variables globales), el compilador * debe * asegurarse de que estén inicializadas * antes * se llama a main(). Incluso las variables estáticas que el programador no establece explícitamente en un valor, * deben * inicializarse a cero o NULL. Esto es requerido por ISO C. – Lundin
@Lundin: buena captura - respuesta actualizada en consecuencia. Gracias. –
¿Qué compilador? –
Dado que la estática tiene diferentes significados, dependiendo del contexto, es una pregunta bastante mala. –
@Paul: a menos que el contexto fuera claro en la pregunta original, pero el asker aquí lo ha dejado afuera. –