Usos del GOTO

3 views
Skip to first unread message

Facundo Viale

unread,
Oct 22, 2010, 10:24:36 AM10/22/10
to c-t...@googlegroups.com
 Buenas! En la actualidad el GOTO es un feature que esta en varios lenguajes ( Incluso en Java O.o ) y que tiene un gran dilema. Por un lado puede simplificar algunas cosas y por otro lado puede hacer que nuestro código se vuelve mas difícil de seguir. Hace unos días estaba mirando un cacho de código del Kernel de Linux y justamente una de las cosas que había notado era el uso de GOTO.

 Encontré una pagina donde citaban ese código del Kernel y mostraban unos ejemplos de uso del GOTO en base a ese código:

typedef struct object {   // A generic struct -- The contents don't matter
  int propertyA, propertyB, propertyC;
} object_t;


errno_t do_something(void){
  FILE *fin1, *fin2;
  object_t *obj;
  errno_t ret_val;
  
  fin1 = fopen("some_file", "r");
  if (fin1 == NULL) {
    return errno;
  }

  fin2 = fopen("some_other_file", "r");
  if (fin2 == NULL) {
    fclose(fin1);
    return errno;
  }

  obj = malloc(sizeof(object_t));
  if (obj == NULL) {
    ret_val = errno;
    fclose(fin1);
    return ret_val;  // forgot to close fin2 !!
  }

  // ... more code ...

  fclose(fin1);
  fclose(fin2);
  free(obj);
  return NOERR;
}

Este código como se puede ver, puede resultar algo repetitivo y molesto. Una solución usando GOTO seria:

// ... assume the same struct as above ...

errno_t do_something(void) {
  FILE *fin1, *fin2;
  object_t *obj;
  errno_t ret_val = NOERR; // Initially assume a successful return value

  fin1 = fopen("some_file", "r");
  if (fin == NULL) {
    ret_val = errno;
    goto FAIL_FIN1;
  }

  fin2 = fopen("some_other_file", "r");
  if (fin2 == NULL) {
    ret_val = errno;
    goto FAIL_FIN2;
  }

  obj = malloc(sizeof(object_t));
  if (obj == NULL) {
    ret_val = errno;
    goto FAIL_OBJ;
  }

  // ... more code ...

SUCCESS:     // Clean up everything
  free(obj);

FAIL_OBJ:   // Otherwise, close only the resources we opened
  fclose(fin2);

FAIL_FIN2:
  fclose(fin1);

FAIL_FIN1:
  return ret_val;
}

A mi criterio, algo así esta permitido siempre y cuando la función no sea grande, el GOTO sean a etiquetas dentro de la función y sea una situación con las mismas características que estos ejemplos se mostró.


Reply all
Reply to author
Forward
0 new messages