Oh, Se me pasó complementar el comentario acerca de la charla que cité anteriormente y no voy a editar un post si alguien ha respondido ya después de publicarlo.
Uno de los ejemplos sobre los cuales en el kernel de linux se usa bastante el goto sería una estructura similar:
pthread_mutex_lock(&m)
if (lo_que_sea){
haz_cosas();
}else{
//no queremos continuar, pero aun asi tenemos que desbloquear
}
//aqui se tendria mucho mas codigo
...
pthread_mutex_unlock(&m);
return algo;
Obviamente, con un lock no parece mucho cambio duplicar el código. Pongamos 15 locks.
En situaciones como estas donde en unos casos la función debería terminar y se han bloqueado diversos locks y que es muy probable que dicho código se vaya a modificar, creo que queda claro que es preferible no duplicarlo en el else sino hacer un goto al final de la función, camino que también se recorrería si la función entrase en el if, haciendo a parte más cosas.
Sea cual sea el caso, al finalizar la función tenemos que soltar esos locks, llegaremos bien sea con un salto directo o bien por el recorrido completo. En este caso creo que se ve que el goto simplifica el código.
saltos para atrás son los que en determinados casos pueden marear la perdiz (aun así, qué son los bucles sino saltos condicionales hacia atrás?), hacia adelante no tienen ningún problema como creo que se puede ver en este ejemplo.