"Niekochane GoTo" Czy zawsze jest złe?

0
procedure ProcedureWithoutAnyInterestingName: boolean;
label
   EXIT;
var
   sl : TStringList;
begin
   sl := TStringList.Create;
   sl.Clear;
   if odEBL.Execute then
   begin
      try
        sl.LoadFromFile(  );
      except
         goto EXIT;
      end;
   end;
EXIT:
   sl.Free;
end;

czy zastosowanie goto w taki sposób jest bardzo złe?
chodzi o to, że wszedzie gdzie czyt się o GoTo widać tylko wielkie czerwone NIE RÓB TEGO. ale Chyba jak nie skacze z jednej funkcji do drugiej tylko jest to taki prosty skok to chyba nie ma problemu? jak to jest?

0

Na moje oko (nie znam języka) gdyby usunąć to goto, to i tak nie zrobiłoby to wielkiej różnicy. Wszystko da się napisać bez goto. Jeżeli twój algorytm musi używać goto, to znaczy że jest zły. Goto jest spuścizną z assemblera i niech w nim pozostanie.

2

@TLesiu: nie można wykonywać goto w bloku except...
Poza tym użycie finally byłoby tutaj znacznie lepszym wyjściem, aniżeli to.

1

Goto jest złym rozwiązaniem w językach wyższego poziomu (niż asm). Poza takimi duperelami jak zaciemnianie kodu, "zmyłki" jak w przykładzie - osobiście spodziewałem się procedury obsługi błędu a nie chamskiego wyjścia, oraz ogólnego paskudnego wyglądu tego typu kodu, instrukcja ta ma dość duży wpływ na sposób działania programu.
W praktyce tak wykonana instrukcja skoku powoduje konieczność przepinania kontekstu. Podobnie jak ma to miejsce przy instrukcjach warunkowych tyle tylko, że taka zmiana będzie znacznie głębsza.

0

Czasem, w kodzie pisanym dla siebie, zdarza mi się takie chamskie goto dodane z lenistwa, by nie przebudowywać całej pętli.
Ale tak naprawdę to rzadko (w zaokrągleniu: nigdy) jest konieczność użycia goto.

Chyba najbardziej uzasadnionym użyciem jest wyskok z zagnieżdżonej pętli:

for ...
   for ...
      for ... do
      begin
         ...
         goto finish;
      end;
finish:

zwykłe break wyskoczy tylko o jeden poziom, a exit od razu z całej funkcji.

powoduje konieczność przepinania kontekstu
Co masz na myśli?

0

Ja przez 17 lat programowania, w tym 7 lat zarabiając tym na życie, nie znalazłem ani jednego miejsca, gdzie goto byłoby najlepszym rozwiązaniem. Wyjątkiem może być wyskakiwanie z wielu zagnieżdżonych w sobie pętli, ale pętle takie stosuje się tak ekstremalnie rzadko, że właściwie można zapomnieć o goto.

0

zawsze można np rzucić wyjątkiem np w środku wielokrotnie zagnieżdżonej pętli jak koniecznie się nie chce używać goto. Pseudokod:

try {
 for(i; i < 1000; i++) {
      for(i; i < 1000; i++) {
            for(i; i < 1000; i++) {
                   if(i  == 100) throw Jumper();
             }  
      }  
  }  
}
catch(Jumper j) {

}
0

zawsze mozna stworzyc zmienna bool i na koncu kazdego fora robic sprawdzenie czy ten bool jest ustawiony na true i wtedy przerywac petle break'iem

1

Zawsze można pisać kod jak człowiek i nie robić więcej niż jednego poziomu zagnieżdżenia...

0

W Delphi jest procedura Abort wywołująca cichy wyjątek EAbort który można obsłużyć w tym miejscu gdzie miała być etykieta do której chcieliśmy skoczyć przez GoTo.

1

Bardzo dobrze jest wiedzieć, że goto istnieje... po to, żeby go nie używać, ale móc użyć. Raz mi się zdarzyło w programie zdecydować się na goto, ale to tłumacząc program z ady tak się pogubiłem, że to było najlepsze wyjście. Reasumując: nie używać, ale wiedzieć, że jest...

0

No, ja od razu wiedziałem, tylko Was sprawdzałem : D, dziekuję, no more Goto;

GoTo HOME;
0

hmm... ja raz nie doznałem bulwersu. W TSQL. Co ciekawe, kod był czytelniejszy.

0

Podsumuję to co już napisałem:

• emulacja goto innymi instrukcjami jest użyciem goto w przebraniu, i większym złem niż goto.
• użycie wyjątku jest dopuszczalne w sytuacji wyjątkowej, błędnej. w programie w którym wszystko przebiega prawidłowo nie powinny wyskakiwać żadne wyjątki. dlatego zastąpienie goto wyjątkiem może być dobre do obsługi błędów, ale nigdy do normalnego zakończenia algorytmu.

Nie chodzi również o dosłowne unikanie słowa goto. Chodzi o unikanie w kodzie takich dzikich skoków nie wiadomo skąd nie wiadomo dokąd.
W 99% przypadków można kod przebudować tak, by nie trzeba było ani goto, ani udawanego goto.

0
Azarien napisał(a):

Chyba najbardziej uzasadnionym użyciem jest wyskok z zagnieżdżonej pętli:

for ...
   for ...
      for ... do
      begin
         ...
         goto finish;
      end;
finish:

zwykłe break wyskoczy tylko o jeden poziom, a exit od razu z całej funkcji.

m.in w java, c#, javascript (a zapewne również w przyszłym C++20) można nazywać pętle i wyskakiwać z wielu na raz

dance: for(;;)
  for(;;)
    for(;;)
      break dance;

tym samym ginie ostatnie zastosowanie dla goto

1 użytkowników online, w tym zalogowanych: 0, gości: 1