Są chwile, kiedy używanie gotojest w rzeczywistości PRAWĄ odpowiedzią - przynajmniej dla tych, którzy nie wychowali się w przekonaniu religijnym, że „ gotonigdy nie może być odpowiedzią, bez względu na pytanie” - i to jest jeden z tych przypadków.
Ten kod używa hackowania do { ... } while(0);wyłącznie w celu przebrania się gotoza break. Jeśli zamierzasz użyć goto, bądź otwarty na ten temat. Nie ma sensu sprawiać, że kod jest trudniejszy do odczytania.
Szczególna sytuacja występuje wtedy, gdy masz dużo kodu o dość skomplikowanych warunkach:
void func()
{
setup of lots of stuff
...
if (condition)
{
...
...
if (!other condition)
{
...
if (another condition)
{
...
if (yet another condition)
{
...
if (...)
...
}
}
}
....
}
finish up.
}
Może sprawić, że JEST CZYSTSZY, że kod jest poprawny, ponieważ nie ma tak złożonej logiki.
void func()
{
setup of lots of stuff
...
if (!condition)
{
goto finish;
}
...
...
if (other condition)
{
goto finish;
}
...
if (!another condition)
{
goto finish;
}
...
if (!yet another condition)
{
goto finish;
}
...
....
if (...)
... // No need to use goto here.
finish:
finish up.
}
Edycja: Aby wyjaśnić, w żadnym wypadku nie proponuję zastosowania gotojako ogólnego rozwiązania. Ale są przypadki, w których gotojest lepsze rozwiązanie niż inne rozwiązania.
Wyobraźmy sobie na przykład, że zbieramy niektóre dane, a różne warunki, które są testowane, to coś w rodzaju „to koniec gromadzonych danych” - który zależy od pewnego rodzaju znaczników „kontynuuj / kończ”, które różnią się w zależności od tego, gdzie jesteś w strumieniu danych.
Teraz, kiedy skończymy, musimy zapisać dane w pliku.
I tak, często istnieją inne rozwiązania, które mogą zapewnić rozsądne rozwiązanie, ale nie zawsze.