Są chwile, kiedy używanie goto
jest w rzeczywistości PRAWĄ odpowiedzią - przynajmniej dla tych, którzy nie wychowali się w przekonaniu religijnym, że „ goto
nigdy 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ę goto
za 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 goto
jako ogólnego rozwiązania. Ale są przypadki, w których goto
jest 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.