Pregunta

Me gustaría saber por qué exactamente estática variables en C, C ++ y Java son inicializadas por cero por defecto? Y por qué esto no es cierto para las variables locales?

¿Fue útil?

Solución

¿Por qué las variables estáticas se inicializan de forma determinista y las variables locales no son?

Vea cómo se implementan las variables estáticas. La memoria para ellos se asigna en tiempo de enlace, y también se proporciona el valor inicial para ellos en tiempo de enlace. no hay sobrecarga de tiempo de ejecución.

Por otro lado, la memoria para las variables locales se asigna en tiempo de ejecución. La pila tiene que crecer. Usted no sabe lo que había antes. Si lo desea, puede borrar esa memoria (cero), pero que incurriría una sobrecarga de tiempo de ejecución. La filosofía de C ++ es "no paga por cosas que no utiliza", por lo que no cero que la memoria por defecto.

bien, pero ¿por qué son las variables estáticas inicializan a cero, y no algún otro valor?

Bueno, por lo general, quiere hacer algo con esa variable. Pero entonces, ¿cómo saber si se ha inicializado? Se puede crear una variable booleana estática. Pero entonces también tiene que ser inicializado de forma fiable a algo (preferiblemente falsa). ¿Qué hay de un puntero? ¿Prefiere lo quiere inicializado a NULL que algunos basura aleatoria. ¿Qué hay de una estructura / registro? Tiene algunos otros miembros de datos en su interior. Tiene sentido para inicializar todos ellos a sus valores por defecto. Sin embargo, por simplicidad, si se utiliza la estrategia de "inicializar a 0", que no tiene que inspeccionar los miembros individuales y comprobar sus tipos. Sólo puede inicializar la totalidad del área de memoria a 0.

Esto no es realmente un requisito técnico. La semántica de inicialización todavía podrían considerarse sano juicio si el valor por defecto es algo distinto de 0, pero todavía determinista. Pero entonces, ¿cuál debería ser ese valor? Usted puede explicar fácilmente por qué se utiliza 0 (aunque de hecho suena un poco arbitrario), pero explicando -1 ó 1024 parece ser aún más difícil (especialmente que la variable puede no ser lo suficientemente grande como para mantener ese valor, etc.).

Y siempre se puede inicializar la variable de forma explícita.

Y siempre tienes el párrafo 8.5.6 de la norma de C ++ que dice "Cada objeto de la duración de almacenamiento estático se inicializa a cero al inicio del programa".

Para obtener más información, por favor refiérase a estas otras preguntas:

Otros consejos

Apartado 8.5.6 de la C ++ estados estándar que:

"Todos los objetos de la duración de almacenamiento estático será cero inicializada al inicio del programa"

(La norma también dice que la inicialización de las variables locales no está definido)

En cuanto a por qué, la norma no dice;). Una conjetura es que es bastante fácil de poner en práctica sin ningún tipo de inconvenientes adicionales

En declaraciones para Java:

variables locales deben inicializarse antes de poder acceder a él, porque es un aumento de la seguridad. El compilador comprueba por ti, si la variable se establece definitivamente.

variables estáticas o de clase (con un tipo de objeto) se inicializan con null, debido a que el compilador no puede comprobar si se inicializan en tiempo de compilación. En lugar de dejar que el programa fracasará si accede a una variable no inicializado, éste se inicializará implícita con null.

Las variables con un tipo nativo no pueden obtener un valor null, por lo que las variables no locales se inicializan con 0 o false, por si falla. No es la mejor solución, seguro, pero no sé una mejor. ; -)

Por lo tanto, en cierta medida estos son sólo el diseño de las decisiones por parte de los diseñadores del lenguaje. Pero las razones probables de estas decisiones en Java son:

  • para las variables estáticas / miembros, si se va a inicializar a algo, entonces cero es un valor conveniente porque (a) por lo general es un valor adecuado para significar "no contiene cualquier otro valor especial", y es el valor que habría recogido todos modos, en algunos casos, tales como contadores; y (b) internamente, es probable que cero se puede utilizar para los valores "especiales", en particular para representar nula en el caso de una referencia de objeto.
  • para las variables locales, dándoles ningún valor predeterminado permite la regla que obliga al programador para establecer algún valor antes de leer la variable, que en realidad puede ser útil para permitir que el compilador para detectar ciertos errores.

En el caso de las variables locales, también es concebible que una variable local podría ser declarada (que a nivel de código / máquina de código de bytes en esencia significa la asignación de espacio de pila / mover el puntero de pila), pero luego en realidad nunca escrito / leído en una determinada ruta de código. Por lo tanto no tener un defecto evita hacer trabajo innecesario de fijar un defecto en esos casos.

repito, sin embargo, se trata de decisiones de diseño en cierta medida. Son esencialmente un compromiso entre lo que es probable que sea conveniente para las implementaciones de JVM y conveniente para los programadores.

N.B. En C / C ++, las variables "estáticas" significan una cosa diferente a las variables estáticas en Java!

No tengo ni idea acerca de Java y dudo que sea diferente para la estática / locales en Java.

En cuanto a C y C ++, se trata de los programadores de preocuparse por su efecto de código y ser amante de control. La inicialización de las variables locales implicaría la ejecución de código extra cada programa de tiempo entra en el ámbito de aplicación. Para que llama con frecuencia funciones que pueden ser un desastre.

Esto tiene que ver con el concepto de "sólo paga por lo que usa" en C / C ++.

Para las variables estáticas, una inicialización se puede hacer sin generar código. El archivo objeto contiene los valores iniciales de las variables en el segmento de datos y cuando el sistema operativo carga las cargas informáticas ejecutables y los mapas de este segmento de datos antes de que el programa comienza su ejecución.

Para las variables locales no hay manera de inicializar ellos sin código, ya que no se inicializan una vez, deben ser inicializadas cada vez que entra en su ámbito de aplicación; También se asignan en la pila, y cuando la asignación se produce el valor inicial de la pila en el caso general no es más que lo que había antes (excepto esos raros momentos que crece la pila más de lo que ha crecido antes).

Así que para inicializar una variable local implícitamente el compilador tendría que generar código sin que el programador mando explícitamente a hacerlo, lo cual es bastante contra el que "la filosofía".

Acerca de Java, por lo que yo sé, las variables siempre se inicializan cuando el programa entra en su ámbito de aplicación, sin importar si son o no estática. La única diferencia significativa entre ellos es que el alcance de las variables estáticas es todo el programa. Teniendo en cuenta que, el comportamiento es consistente entre todos ellos.

Esto es sólo una suposición, pero puede ser que sea la forma en que es para la estática ya que es fácil de implementar, y útil.

El compilador puede co-asignar todas las variables en una sola área de memoria contigous, y luego o bien emitir código (una sola llamada memset()) para desactivarla antes main() se llama. En muchos casos también puede depender de características de formato de archivo ejecutable del sistema operativo, si ese formato compatible " bss secciones ", que se eliminan por el cargador en su lugar. Esto ahorra espacio en el ejecutable, puede tener

static unsigned char megabyte[1 << 20];

y el ejecutable no crecería por una megabyte.

Para las variables locales, ninguna de estas situaciones; que se asignan "sobre la marcha" (por lo general en una pila) y sería un desperdicio de recursos para eliminarlas, ya que son por lo general va a ser asignado a muy pronto de todos modos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top