Fran escribió
hace 1 años
sharek escribió
hace 1 años
Yo opino que goto está allí para usarse y debe usarse, igual que los comentarios en el código, eso evitará los problemas de comprensión del flujo :)
Al fin y al cabo, en ensamblador SOLO existen los gotos (jmp y similares)
goto es rápido, ahorra memoria y es muy útil, por mucho que sea considerado una mala práctica
erpelu escribió
hace 1 años
A mi me gusta más una función a la cual le pasamos por referencia todas esas variables y ahí haces el free.
También pienso que una función es más comprensible para leer código que un goto. Si un programa tiene 100 lineas puede valer, pero a la que tengas 10 o 15 ficheros de (por ejemplo)más de 500 líneas a ver donde se va con goto's....
Luix escribió
hace 1 años
No, nunca he usado goto. De todos modos en programación, como en tantos aspectos de la vida (qué romántico) no existe solamente el blanco y el negro. Si lo usas razonadamente y con una justificación clara, hazlo, pero sobre todo, ¡coméntalo bien en el código! Así el que venga detrás lo leerá mejor, y sobre todo no pensará que eres un chapucero, sino que adoptaste una determinada solución por tales o cuales razones.
sharek: el hecho de que en ensamblador sólo haya gotos es la misma por la cual en ensamblador no hay DataSets, ni árboles, ni listas enlazadas. Estamos hablando de un nivel de abstracción mucho menor. No tiene nada que ver con que no existan otras estructuras del lenguaje. De todos modos en ensamblador no existen "gotos", existen "saltos". Un goto es un salto de ensamblador adaptado a un lenguaje de más nivel de abstracción, no viceversa.
Konum escribió
hace 1 años
Opino como erpelu. Personalmente prefiero una función que haga eso mismo. Pero para gustos colores, y si te resulta cómodo usarlos no hay nadie que lo impida :P
Fran escribió
hace 1 años
Después de mucho tiempo hay respuestas en este mensaje.
A mí lo de la función no me convence, porque puede haber diferentes tipos de variables que puede que no se liberen con un sencillo free.
Si me ponéis un ejemplo de cómo lo haríais a lo mejor me lográis convencer. ;)
Luix escribió
hace 1 años
¡Jajaja, pues es verdad! Pero que conste que yo he contestado porque el comentario salía en portada y me llamó la atención.
Pides ejemplos, pero si no facilitas tú el caso en el cual tienes dudas... poco podremos decirte... :P:P:P
Te lo iba a haber dicho en el otro comentario. Tal cual lo comentas, una función liberar() y otra tratarError() parece lo más indicado. Danos más detalles...
Fran escribió
hace 1 años
Veamos, os voy a intentar poner un ejemplo dónde yo suelo usar goto.
int funcion () {
FILE *fichero;
char *cadena;
MiEstructura *estructura;
fichero = fopen ("Fichero", "r");
if (fichero == NULL)
return -1;
cadena = (char *) malloc (strlen ("hola") + 1);
if (cadena == NULL) {
fclose (fichero);
return -2;
}
strcpy (cadena, "hola");
estructura = (MiEstructura *) malloc (sizeof (MiEstructura));
if (estructura == NULL) {
fclose (fichero);
free (cadena);
return -3;
}
/* Realizar operaciones */
fclose (fichero);
free (cadena);
estructura_free (estructura);
return 0;
}En este ejemplo, no he usado goto y podéis comprobar que cada vez que realizo una operación que puede fallar (como el malloc), al comprobar si dicha operación falla tengo que meter un buen trozo de código (que va creciendo según reservo memoria para más variables) liberando la memoria, además dicho código también lo tengo que poner al final del código antes de salir de la función.
Ahora usando goto veréis como el código queda algo más ordenado y, sobre todo, limpio.
int funcion () {
FILE *fichero = NULL;
char *cadena = NULL;
MiEstructura *estructura = NULL;
int ret = 0;
fichero = fopen ("Fichero", "r");
if (fichero == NULL) {
/* Aquí se podría poner return -1; */
ret = -1;
goto CleanUp;
}
cadena = (char *) malloc (strlen ("hola") + 1);
if (cadena == NULL) {
ret = -2;
goto CleanUp;
}
strcpy (cadena, "hola");
estructura = (MiEstructura *) malloc (sizeof (MiEstructura));
if (estructura == NULL) {
ret = -3;
goto CleanUp;
}
/* Realizar operaciones */
/* Liberar memoria */
CleanUp:
if (fichero != NULL)
fclose (fichero);
if (cadena != NULL)
free (cadena);
if (estructura != NULL)
estructura_free (estructura);
return ret;
}Ahora, mi pregunta es: ¿Cómo lo harías con una función, si el número de variables no es fijo y además puede haber variables de distintos tipos que necesitan sus propias funciones para liberar memoria como podría ser una estructura?
Luix escribió
hace 1 años
Si no he entendido mal, el mismo problema que planteas para la función podrías tenerlo para el goto. Yo haría una función Liberar(nombre_variable, tipo) y dentro de esa función un case: según cada tipo, llamar a una función LiberaMemoria(nombre_variable), CierraFichero(nombre_variable), LiberaEstructura(nombre_variable).
Ventajas:
Y desde el punto de vista de la cohesión y el acoplamiento es perfecto.
¿Funcionaría o no he entendido bien el problema?
Fran escribió
hace 1 años
Me ha gustado la idea, pero me sigue sin convencer, que se le va a hacer. :P
Yo diría que legible precisamente no es, porque es una función que crecería en tamaño rápidamente y sería un follón de casos.
Es que no me gustan las funciones haztodoloquepuedasymas soy de la opinión de haz lo que debes y punto, hazlo simple (Keep It Simple que dicen por los países anglosajones).
Luix escribió
hace 1 años
Si, hombre, pero la extensibilidad no es la única ventaja que te comento... también depende de para qué vayas a aplicar esa solución. Si es para algo personal no es lo mismo que si es para un proyecto empresarial que va a sufrir modificaciones y ampliaciones y va a mantener otra persona...
« Anterior 1 2 3 4 Siguiente »
© Copyright 2008-2009 debug_mode=ON | Aviso legal | Contacto | FAQ | ¿Quiénes somos? |
Hola.
De siempre he oído que usar goto para programar no está bien, no es aconsejable, hace que la lectura del código sea más difícil, ...
Pero desde hace tiempo me he dado que usar algún goto me ha mejorado la vida y, por ejemplo, hace que mi código sea más pequeño, con menos repeticiones de código y en mi opinión más sencillo de leer.
Claro está, que para ello hay que usar goto con mucho cuidado y sin pasarse, yo lo suelo usar para limpiar la memoria, me voy a explicar:
En una función en la que tienes bastantes variables cuya memoria has reservado dinámicamente, y tienes que usar en todo (o casi todo) el código, al final cada vez que controles cualquier error dentro de dicha función tendrás que liberar la memoria con su consecuente porrón de frees, entonces en estos caso lo que suelo hacer es crear un goto para liberar la memoria, que tiene todo ese porrón de frees y cada vez que se produce un error, realizo el goto.
¿Qué opináis vosotros? ¿Os gusta usar goto? ¿Alguna sugerencia que dar?