2010-08-09 4 views
8

En muchos idiomas, puede declarar una variable y usarla antes de inicializarla.¿Qué beneficio hay en permitir que una variable se deje sin inicializar?

Por ejemplo, en C++, se puede escribir un fragmento tales como:

int x; 
cout << x; 

Esto, por supuesto, volver impredecible (bueno, a menos que sepa cómo su programa fue trazando memoria) resultados, pero mi pregunta es, ¿por qué este comportamiento es permitido por los compiladores?

¿Existe alguna aplicación o eficiencia que resulte de permitir el uso de memoria no inicializada?

edit: Se me ocurrió que dejar la inicialización al usuario minimizaría las escrituras para los medios de memoria que tienen vidas útiles limitadas (ciclos de escritura). Solo un ejemplo específico bajo el encabezado de "rendimiento" antes mencionado. Gracias.

Respuesta

1

Quizás en algunos casos, es más rápido dejar la memoria sin inicializar hasta que sea necesaria (por ejemplo, si regresa de una función antes de usar una variable). Normalmente inicializo todo de todos modos, dudo que haga una diferencia real en el rendimiento. El compilador tendrá su propia manera de optimizar las inicializaciones inútiles, estoy seguro.

4

La excusa más antigua en programación: ¡mejora el rendimiento!

editar: lea sus comentarios y estoy de acuerdo: hace años, el foco en el rendimiento estaba en el número de ciclos de la CPU. Mi primer compilador de C era C tradicional (el anterior a ANSI C) y permitía compilar todo tipo de abominaciones. En estos tiempos modernos, el rendimiento se trata de la cantidad de quejas de los clientes. Cuando les digo a los nuevos graduados contratamos: "No me importa qué tan rápido el programa da una respuesta incorrecta". Use todas las herramientas de desarrollo y compiladores modernos, escriba menos errores y todos puedan irse a casa a tiempo.

+2

¿No mejoraría más el rendimiento al no declararlo? De esa forma, la memoria ni siquiera necesitaría asignarse para la variable. Cualquiera que cite el rendimiento para este tipo de código es simplemente incorrecto. –

+1

La palabra clave es * más antigua *. Hace 40 años, cuando C se estaba desarrollando, "desperdiciar" una instrucción o dos para autoinicializar una variable realmente podría haber importado. – dan04

+0

Perder una instrucción podría haber sido valioso, pero en el sentido de rendimiento, tener esa instrucción adicional (o dos o tres) haría que la aplicación fuera menos eficiente. –

1

Algunos idiomas tienen valores predeterminados para algunos tipos de variables. Dicho esto, dudo que haya beneficios de rendimiento en ningún idioma para no inicializarlos explícitamente. Sin embargo, las desventajas son:

  • La posibilidad de que debe iniciarse y sin ser hecho corre el riesgo de un accidente
  • valores anticipados
  • La falta de claridad y propósito para otros programadores

Mi sugerencia siempre inicializa tus variables y la consistencia se amortizará sola.

4

Algunas API de están diseñados para devolver datos a través de variables pasadas en, por ejemplo:

bool ok; 
int x = convert_to_int(some_string, &ok); 

Se puede establecer el valor de 'bien' dentro de la función, por lo inicializando que es un desperdicio.

(no estoy abogando por este estilo de la API.)

+1

Para el uso del "mundo real" de esto, consulte la clase QString de Qt: http://doc.qt.nokia.com/4.6/qstring.html#toInt como ejemplo. Note el bool * ok. – sivabudh

+0

depende del parámetro de función si están OUT-typed, o INOUT-typed. – YeenFei

+1

Lo mismo con flujos de entrada estándar: 'bool ok; std :: cin >> ok; ' – rafak

13

Mis pensamientos (y me he equivocado antes, sólo hay que preguntar a mi esposa) son que es simplemente un vestigio de encarnaciones anteriores de la lengua .

Las primeras versiones de C no le permitían declarar las variables en cualquier lugar que deseara en una función, tenían que estar en la parte superior (o tal vez al comienzo de un bloque, es difícil recordarlo desde Raramente hago eso hoy en día).

Además, tiene el deseo comprensible de establecer una variable solo cuando sabe lo que debería ser. No tiene sentido inicializar una variable para algo si lo siguiente que va a hacer con ella es simplemente sobrescribir ese valor (de ahí viene la gente de rendimiento).

Es por eso que es necesario para permitir que las variables no inicializadas, aunque aún debe no uso ellos antes de inicializar, y los buenos compiladores tener advertencias para hacerle saber al respecto.

En C++ (y encarnaciones posteriores de C) donde puede crear su variable en cualquier lugar de una función, realmente debe crearla e inicializarla al mismo tiempo. Pero eso no fue posible desde el principio. Había que usar algo como:

int fn(void) { 
    int x, y; 
    /* Do some stuff to set y */ 
    x = y + 2; 
    /* Do some more stuff */ 
} 

Hoy en día, me gustaría optar por:

int fn(void) { 
    int y; 
    /* Do some stuff to set y */ 
    int x = y + 2; 
    /* Do some more stuff */ 
} 
+0

+1 Viniendo de ser un C/C++ durante muchos años lo hago. Estaba escribiendo una respuesta a lo largo de esta línea también, me la ganaste :) Es aconsejable inicializar una variable con un valor significativo lo más cercano a la lógica de código principal que lo usa como sea posible: métricas de distancia. –

+0

@ozmo, esta debería ser la respuesta aceptada. – sivabudh

+1

+1 para los compiladores modernos lo advertirán. Simplemente coloque el nivel de advertencia al más alto nivel y luego realice todos los errores de advertencia y tendrá el mismo efecto que obligar a las personas a inicializar antes de su uso. El hecho de que los humanos sean perezosos no significa que no podamos compensarlo con compiladores inteligentes :-) Larga vida o compiladores supremos. –

2

La respuesta corta es que para los casos más complicados, el compilador no puede ser capaz de determinar si una variable se usa antes de la inicialización o no.

por ejemplo.

int x; 
if (external_function() == 2) { 
    x = 42; 
} else if (another_function() == 3) { 
    x = 49; 
} 
yet_another_function(&x); 
cout << x; // Is this a use-before-definition? 

buenos compiladores darán un mensaje de advertencia si se puede detectar un error probable de uso antes de inicializar, pero para los casos complejos - especialmente la participación de múltiples unidades de compilación - no hay manera para que el compilador que contar.

En cuanto a si un lenguaje debe permitir el concepto de variables no inicializadas, esa es otra cuestión. C# es un poco inusual al definir cada variable como inicializada con un valor predeterminado. La mayoría de los lenguajes (C++/C/BCPL/FORTRAN/Assembler/...) le dejan al programador si la inicialización es apropiada. Los buenos compiladores a veces pueden detectar inicializaciones innecesarias y eliminarlas, pero esto no es un hecho. Los compiladores para hardware más oscuro tienden a tener menos esfuerzo puesto en la optimización (que es la parte más difícil de la escritura del compilador), por lo que los lenguajes dirigidos a dicho hardware tienden a no requerir la generación innecesaria de código.

0

Dependiendo del tamaño de la variable, dejar el valor sin inicializar en nombre del rendimiento puede considerarse una micro-optimización. Relativamente pocos programas (en comparación con la amplia gama de tipos de software que existen) se verían negativamente afectados por los dos o tres ciclos adicionales necesarios para cargar un doble; sin embargo, suponiendo que la variable fuera bastante grande, probablemente sea una buena idea retrasar la inicialización hasta que se requiera una inicialización abundantemente clara.

0

para el estilo de bucle

int i; 
for(i=0;i<something;++i){ 
    ....... 
} 
do something with i 

y prefiere el bucle para que parezca for(init;condition;inc)

aquí hay uno con una necesidad absoluta

bool b; 
do{ 
    .... 
    b = g(); 
    .... 
}while(!b); 

horizontal de la pantalla de bienes raíces con nombres anidados largos

alcance de mayor duración para debuggin g visibilidad

muy ocasionalmente rendimiento

Cuestiones relacionadas