¿Qué tan importante es inicializar variables?
¿La inicialización adecuada evita pérdidas de memoria o tiene ventajas de rendimiento?
¿Qué tan importante es inicializar variables?
¿La inicialización adecuada evita pérdidas de memoria o tiene ventajas de rendimiento?
null
compiladores comunes inicializan las variables locales a 0 (o ), pero son basura aleatoria cuando se compilan para su lanzamiento. (aunque mi conocimiento de C ++ es de hace ~ 10 años, las cosas pueden haber cambiado)Respuestas:
Las variables no inicializadas hacen que un programa no sea determinista. Cada vez que se ejecuta el programa, puede comportarse de manera diferente. Los cambios no relacionados con el entorno operativo, la hora del día, la fase de la luna y las permutaciones de tales afectan cómo y cuándo se manifiestan estos demonios. El programa puede ejecutarse un millón de veces antes de que se presente el defecto, puede hacerlo cada vez o ejecutar otro millón. Muchos problemas se atribuyen a "problemas técnicos" y se ignoran, o los informes de defectos de los clientes se cierran como "No reproducibles". ¿Con qué frecuencia ha reiniciado una máquina para 'solucionar' un problema? ¿Con qué frecuencia le ha dicho a un cliente "Nunca he visto que eso suceda, avíseme si lo ve de nuevo", con la esperanza (sabiendo) que no lo harán!
Como la reproducción de un defecto puede ser casi imposible en el entorno de prueba, es casi imposible de encontrar y corregir.
El error puede tardar años en aparecer, comúnmente en el código que se considera confiable y estable. Se presume que el defecto está en un código más reciente; rastrearlo puede llevar mucho más tiempo. Un cambio en el compilador, un cambio de compilador, incluso agregar una línea de código puede cambiar el comportamiento.
Inicializar variables tiene una gran ventaja de rendimiento, no solo porque un programa que funciona correctamente es infinitamente más rápido que uno que no lo hace, sino que los desarrolladores pasan menos tiempo buscando y reparando defectos que no deberían estar allí y más tiempo haciendo un trabajo "real".
La otra ventaja significativa de inicializar variables es que el autor original del código debe decidir a qué inicializarlas. Esto no siempre es un ejercicio trivial, y cuando no lo es, puede ser una indicación de un mal diseño.
Las pérdidas de memoria son un problema diferente, pero una inicialización adecuada no solo puede ayudar a prevenirlas, sino que también puede ayudar a detectarlas y encontrar la fuente: depende en gran medida del idioma y esa es realmente una pregunta separada que merece más exploración de la que puedo ofrecer. en esta respuesta
Editar: en algunos lenguajes (p. Ej., C #) no es posible usar variables no inicializadas, ya que el programa no compilará o informará un error cuando se ejecute, si se hace. Sin embargo, muchos lenguajes con estas características tienen interfaces para código potencialmente inseguro, por lo que se debe tener cuidado al usar tales interfaces no para introducir variables no inicializadas.
fuente
Inicializar una variable como señaló Telastyn puede evitar errores. Si la variable es un tipo de referencia, inicializarla puede evitar errores de referencia nulos en el futuro.
Una variable de cualquier tipo que tenga un valor predeterminado no nulo ocupará algo de memoria para almacenar el valor predeterminado.
fuente
Intentar usar una variable no inicializada siempre es un error, por lo que tiene sentido minimizar la probabilidad de que ocurra ese error.
Probablemente, el enfoque más común que toman los lenguajes de programación para mitigar el problema es inicializar automáticamente a un valor predeterminado, por lo que al menos si olvida inicializar una variable, será algo así como
0
algo diferente0x16615c4b
.Esto resuelve un gran porcentaje de errores, si de todos modos necesita una variable inicializada a cero. Sin embargo, usar una variable que se inicializó con un valor incorrecto es tan malo como usar una que no se inicializó en absoluto. De hecho, a veces puede ser aún peor, porque el error puede ser más sutil y difícil de detectar.
Los lenguajes de programación funcional resuelven este problema no solo rechazando valores no inicializados, sino también rechazando la reasignación por completo. Eso elimina el problema y resulta que no es una restricción tan severa como podría pensar. Incluso en lenguajes no funcionales, si espera declarar una variable hasta que tenga un valor correcto para inicializarla, su código tiende a ser mucho más robusto.
En cuanto al rendimiento, probablemente sea insignificante. En el peor de los casos, con variables no inicializadas, tiene una asignación adicional y vincula algo de memoria por más tiempo del necesario. Los buenos compiladores pueden optimizar las diferencias en muchos casos.
Las pérdidas de memoria no tienen relación alguna, aunque las variables correctamente inicializadas tienden a estar dentro del alcance por un período de tiempo más corto y, por lo tanto, es menos probable que un programador pierda accidentalmente.
fuente
Inicializar, implica que el valor inicial es importante. Si el valor inicial importa, entonces sí, claramente debe asegurarse de que esté inicializado. Si no importa, eso implica que se inicializará más tarde.
La inicialización innecesaria causa ciclos de CPU desperdiciados. Si bien estos ciclos desperdiciados pueden no importar en ciertos programas, en otros programas, cada ciclo es importante ya que la velocidad es una preocupación principal. Por lo tanto, es muy importante comprender cuáles son los objetivos de rendimiento y si las variables deben inicializarse o no.
Las pérdidas de memoria son un problema completamente diferente que generalmente implica una función de asignación de memoria para emitir y luego reciclar bloques de memoria. Piensa en una oficina de correos. Ve y pide un buzón. Te dan uno. Pides otro. Te dan otra. La regla es que cuando termine de usar un buzón de correo, debe devolverlo. Si olvida devolverlo, todavía piensan que lo tiene, y la caja no puede ser reutilizada por nadie más. Por lo tanto, hay un trozo de memoria atado y no se usa, y esto es lo que se conoce como pérdida de memoria. Si sigue pidiendo cajas en algún momento, se quedará sin memoria. He simplificado demasiado esto, pero esta es la idea básica.
fuente
Como otros dijeron, depende del idioma. Pero demostraré mis ideas de Java (y Java efectivo) sobre la inicialización de variables. Estos deberían ser utilizables para muchos otros idiomas de nivel superior.
Constantes y variables de clase
Las variables de clase, marcadas con
static
en Java, son como constantes. Estas variables normalmente deberían ser finales e inicializadas directamente después de la definición usando=
o desde un bloque de inicializador de clasestatic { // initialize here }
.Campos
Como en muchos idiomas de nivel superior y scripting, los campos se asignarán automáticamente a un valor predeterminado. Para números y
char
este será el valor cero. Para cadenas y otros objetos seránull
. Ahoranull
es peligroso y debe usarse con moderación. Por lo tanto, estos campos deben establecerse en un valor válido lo antes posible. El constructor es normalmente un lugar perfecto para esto. Para asegurarse de que las variables se establecen durante el constructor y no se cambian después, puede marcarlas con lafinal
palabra clave.Intenta resistir el impulso de usar
null
como algún tipo de bandera o valor especial. Es mejor, por ejemplo, incluir un campo específico para mantener el estado. Un campo con el nombrestate
que usa los valores de unState
enumeración sería una buena opción.Parámetros del método
Como la persona que llama no verá los cambios en los valores de los parámetros (ya sea referencias a objetos o tipos básicos como enteros, etc.), los parámetros deben marcarse como
final
. Esto significa que los valores de la variable en sí no se pueden cambiar. Tenga en cuenta que el valor de las instancias de objeto mutable se puede cambiar, la referencia no se puede cambiar para apuntar a un objeto diferente onull
aunque.Variables locales
Las variables locales no se inicializan automáticamente; deben inicializarse antes de poder usar su valor. Un método para asegurarse de que su variable se inicialice es inicializarla directamente a algún tipo de valor predeterminado. Sin embargo, esto es algo que no deberías hacer. La mayoría de las veces el valor predeterminado no es un valor que esperaría.
Es mucho mejor definir solo la variable precisamente donde la necesita. Si la variable solo toma un valor único (lo cual es cierto para la mayoría de las variables en buen código), entonces puede marcar la variable
final
. Esto asegura que la variable local se asigne exactamente una vez, no cero veces o dos veces. Un ejemplo:Tenga en cuenta que muchos idiomas le avisarán si una variable permanece sin inicializar antes de su uso. Consulte las especificaciones de idioma y los foros para ver si no se preocupa innecesariamente.
fuente
No hay problema con las variables de inicialización.
El problema es solo cuando lee una variable que aún no se ha escrito.
Dependiendo del compilador y / o del tipo de variable, la inicialización se realiza al inicio de la aplicación. O no.
Es de uso común no confiar en la inicialización automática.
fuente
Inicializar variables (implícita o explícitamente) es crucial. No inicializar una variable siempre es un error (sin embargo, podrían inicializarse implícitamente. Ver más abajo). Los compiladores modernos como el compilador de C # (como ejemplo) tratan esto como un error y no le permiten ejecutar el código. Una variable no inicializada es simplemente inútil y dañina. A menos que esté creando un generador de números aleatorios, espera que un código produzca un resultado determinista y reproducible. Esto solo se puede lograr si comienza a trabajar con variables inicializadas.
La pregunta realmente interesante es si una variable se inicializa automáticamente o si tiene que hacerlo manualmente. Depende del idioma utilizado. En C #, por ejemplo, los campos, es decir, "variables" a nivel de clase, siempre se inicializan automáticamente al valor predeterminado para ese tipo de variable.
default(T)
. Este valor corresponde a un patrón de bits que consiste en todos los ceros. Esto es parte de la especificación del lenguaje y no solo un detalle técnico de la implementación del lenguaje. Por lo tanto, puede confiar en él de manera segura. Es seguro no inicializar una variable explícitamente si (y solo si) la especificación del lenguaje establece que se inicializa implícitamente.Si desea otro valor, debe inicializar la variable explícitamente. Sin embargo; en C # las variables locales, es decir, las variables declaradas en los métodos, no se inicializan automáticamente y siempre debe inicializar la variable explícitamente.fuente