Goto naredba
Goto naredba. Ova naredba vrši bezuslovni prenos kontrole toka na odgovarajuće mesto u kodu obeleženo odgovarajućom labelom (koja ima oblik identifikatora). Za ovu naredbu skoka je pokazano da nije neophodna odnosno da se svaki program koji u sebi sadrži pomenutu naredbu može zameniti programom koji daje isti rezultat a ne koristi ovu naredbu vec koristi sekvencijalno izvršavanje naredbi, naredbe odlučivanja i jednu vrstu petlje (Teorema o strukturnom programiranju). U prošlosti je postojala ozbiljna naučna debata o upotrebi goto naredbe u programiranju.

Upotreba
Goto naredba se obično koristi u kombinaciji sa If naredbom, koja može izazvati uslovni prenos kontrole. Programski jezici nameću razna ograničenja u odnosu na odredište Goto naredbe. Na primer, programski jezik -{C}- ne dozvoljava skok na etikete koje su sadržane u nekoj drugoj funkciji.

Teorema o strukturnom programiranju
Strukturno programiranje je vid programiranja nastao sedamdesetih godina, a prethodilo mu je kompozitno programiranje. Tadašnje novonastale velike mogućnosti hardvera softver nije mogao da isprati, što je dovelo do prve softverske krize. 1968. godine holandski informatičar Edsher Dajkstra (-{Edsger Wybe Dijkstra}-) napisao je članak o štetnosti Goto naredbe u kojem je izneo zanimljivu činjenicu da je broj grešaka u softveru proporcionalan broju upotreba goto naredbe. Godinu dana kasnije, tačnije 1969. godine stvoren je programski jezik koji je omogućio pisanje programa bez pomenute goto naredbe. To je bio jezik -{Pascal}- (-{Niklaus Virt}-). Godine 1972. pojavila se knjiga "Strukturirano programiranje" (autora pomenutog Dijkstre, Hoara i Dahla) u kojoj se nalaze članci vezani za rešavanje problema bez upotrebe ove naredbe. 
1966. godine C. Boehm i G. Jakopini dokazali su teoremu o strukturnom programiranju (-{Böhm-Jacopini}- teorema): Svaki programski zadatak je moguće logički ostvariti primenom samo elementarnih struktura sekvence, izbora i ponavljanja. Primena ove teoreme nas dovodi do potrebe utvrđivanja metodologije razvoja programskih struktura. Najčešće se koristi -{top-down}- metoda.

Špageti kod
Špageti kod je fraza koja se koristi za izvorni kod koji ima kompeksnu i zamršenu upravljačku strukturu, posebno onda kada koristi mnogo goto naredbi, izuzetaka i drugih "nestrukturnih" konstrukcija. Ime je dobrio baš po tome što je tok programa konceptualno kao činija špageta, uvrnut i zamršen. Špageti kod može nastati iz više razloga, kao na primer, neprekidne izmene od strane ljudi koji imaju različite stilove programiranja. Strukturno programiranje uveliko smanjuje učestalost špageti koda.

U nastavku sledi jedan trivijalni primer Špageti koda. Program štampa brojeve od 1 do 10, zajedno sa njihovim kvadratima. Uočimo da se uvlačenje ne koristi da bi se razlikovale različite akcije koje se izvršavaju, i da goto naredba zavisi od broja linija koda. Špageti kod u praksi je mnogo komplikovaniji i može u velikoj meri povećati troškove održavanja programa.

10 i = 0
20 i = i + 1
30 PRINT i; " Kvadrat broja je "; i * i
40 IF i >= 10 THEN GOTO 60
50 GOTO 20
60 PRINT "Program je završen."
70 END

Isti kod napisan u stilu strukturnog programiranja izgledao bi ovako:

10 FOR i = 1 TO 10
20 PRINT i; " Kvadrat broja je "; i * i
30 NEXT i
40 PRINT "Program je završen."
50 END

Prilikom upotrebe nižih programskih jezika i mašinskih jezika postoji velika opasnost pisanja špageti koda. S druge strane, usvajanjem istog režima kao i u strukturnom programiranju mogu se znatno poboljšati čitljivost i održavanje koda. Ovo se može postići, na primer, uvođenjem limita za upotrebu goto naredbi. Neki od široko korišćenih programskih jezika, kao što su -{Python}- i -{Java}-, nemaju goto naredbu, i stoga snažno podržavaju koncept strukturnog programiranja.

Istorija
Goto naredba pojavila se još kod prvih viših progaramskih jezika. Iako je na sastanku vezanom za tada novonastali programski jezik -{Algol}- 1959. godine Heinz Zemanek eksplicitno bacio sumnju na neophodnost Goto naredbe, niko u to vreme nije obratio pažnju na njegovu opasku, uključujući i Edsger Dijkstra, koji će kasnije postati kultni protivnik Goto naredbe. 1970-ih i 1980-ih zabeležen je pad u korišćenju Goto naredbe što je išlo u korist paradigmi strukturnog programiranja, koja je dovela do špageti koda. Medjutim, uprkos svim lošim stranama Goto naredbe i velikom broju njenih protivnika ona se pojavila i u sintaksi jezika nove generacije, kao sto su -{C++}- i -{Java}-, doduše u Javi je samo rezervisana reč goto ali se ne upotrebljava.

Pozitivne kritike
Goto naredba kao takva nije naišla na veliki broj pozitivnih kritika. Ona svojom suštinom podseća na instrukcije koje se zadaju na asemblerskom nivou. Pozitivna strana ove naredbe jeste visok nivo kontrole koju programer dobija njenom upotrebom.

Negativne kritike
Neki od standardnih stilova kodiranja ne preporučuju korišćenje Goto naredbe. Jedna od najpoznatijih kritika našla se upravo u pismu Edsger Dijkstra 1968. gde je tvrdio da neograničena Goto naredba treba biti ukinuta kod jezika višeg reda, jer komplikuje zadatak analiziranja i provere ispravnosti programa. Postojali su i oni koji su smatrali da je naredba skoka korisna, pa su u -{C}- program ubacili još dve naredbe skoka - -{Break}- i -{Continue}-. Drugi su, međutim, smatrali da su čak i varijacije poput -{break}- i -{return}- usred petlje jako loše i nepotrebne u praksi i baš iz tog razloga su se zalagali da postoji samo jedan izlaz iz petlje.

Primeri upotrebe
U ovom pasusu nalaze se primeri upotrebe naredbe goto u raznim programskim jezicima.

Programski jezik -{C}-
    #include<stdio.h>
 
    int main(){
      int x=10;

      PETLJA: do{
        if(x==13){
          x++;
          goto PETLJA;
        }

      printf("Vrednost promenljive x je : %d\n",x);
      x++;
      }while(x<=15);

      return 0;
    }

Programski jezik -{Java}-
Programski jezik -{Java}- u svom spisku rezervisanih odnosno ključnih reči rezerviše reč -{goto}-, međutim ova reč još uvek nema svoju upotrebu u istom jeziku (oznacena jednom zvezdicom kao -{*not used}- u zvaničnoj dokumentaciji).

Programski jezik -{Delphi}-

    var
      i : Integer;

    label
      GotoLabel;

    begin
      for i := 1 to 10 do
      begin
        ShowMessage('i = '+IntToStr(i));

        if i = 4 then Goto GotoLabel;   // Uslovni izlazak iz petlje
      end;

      ShowMessage('Petlja uspešno izvršena');
    GotoLabel:
      ShowMessage('Petlja završena sa i = '+IntToStr(i));
    end;

Programski jezik -{C++}-

    # include <iostream>
    using namespace std;

    int main()
    {
        float num, average, sum = 0.0;
        int i, n;

        cout << "Maksimalni broj ulaza: ";
        cin >> n;

        for(i = 1; i <= n; ++i)
        {
            cout << "Unesi n" << i << ": ";
            cin >> num;
        
            if(num < 0.0)
            {
               // Kontrola toka na labelu skok
                goto skok;
            } 
            sum += num;
        }
    
    skok:
        average = sum / (i - 1);
        cout << "\nAverage = " << average;
        return 0;
    }

Programski jezik -{Pascal}-

    program exGoto;
    label 1; 
    var
       a : integer;

    begin
       a := 10;
       (* Ponavljaj dok se petlja izvršava *)
       1: repeat
          if( a = 15) then
      
          begin
             (* Preskoči iteraciju *)
             a := a + 1;
             goto 1;
          end;
      
          writeln('value of a: ', a);
          a:= a +1;
       until a = 20;
    end.

Alterantive

Strukturno programiranje

Radi bolje jasnoće i efikasne optimizacije, jezici koji podržavaju strukturno prgramiranje (kao na primer -{Pascal}-) uveli su kontrole strukture kao što su:

 procedure ili funkcije, 
 petlje (-{while, repeat until}- ili -{do, for}- naredba),
 -{swich - case}- naredba, vrsta višestrukog grananja.

Ovi novi jezički mehanizmi zamenili su ekvivalentne tokove koju su se prethodno pisali upotrebom -{goto}- i -{if}- naredbi. Višestruko grananje zamenjuje goto naredbu u kojoj se instrukcija na koju treba preći određuje dinamički (uslovno).

Izuzeci

U praksi, strogo pridržavanje osnovnog tri-strukturalnog šablona strukturnog programiranja, dovodi do visoko ugnježdenog koda i do nemogućnosti momentalnog izlaza iz strukturne jedinice.

Za ovaj problem postoje dva najčešće korišćena rešenja: način da se momentalno izađe iz strukturne jedinice i izuzeci. U oba slučaja kontrola se vraća na zatvarajuće blokove funkcije, a ne skače se na proizvoljnu lokaciju u kodu. Ovo je analogno upotrebi return naredbe. U C-u, naredbe -{break}- i -{continue}- dozvoljavaju da se petlja završi ili da se nastavi sa sledećom iteracijom, bez potrebe da dodatnom -{while}- ili -{if}- naredbom. U nekim jezicima moguća je upotreba -{break}- naredne na višestrukom nivou. Za rukovanje specijalnim situacijama dodate su konstrukcije za upravljanje izuzecima, kao što su -{try/catch/finally}- u programskom jeziku -{Java}-.

Mehanizam za upravljanje -{throw-catch}- izuzecima može, takođe, biti zloupotrebljen za pravljenje netransparentne upravljačke struktrure, baš kao i -{goto}- naredba.

Korutine

Korutine dozvoljavaju ne samo višestruke tačke izlaza iz neke strukturne jedinice, već i višestruke ulaze, slično kao i goto naredba. Korutine su restriktivnije od goto naredbe, jer one mogu da nastave samo trenutno pokrenutu korutinu, i ne skaču na proizvolju liniju u kodu.

-{Continuation}- naredba

-{Continuation}- naredba je slična goto naredbi po tome što vrši prenos kontrole sa proizvoljne tačke u programu na prethodno označenu tačku. Ova naredna je fleksibilnija od goto naredbe u jezicima koji je podržavaju, jer može preneti kontrolu izvan trenutne funkcije, a to goto naredbom nije moguće postići u mnogim strukturnim programskim jezicima.

Prenošenje poruka

U neproceduralnim paradigmama, goto naredba je manje relevantna ili potpuno odsutna. Jedna od glavnih alternativa je "prenošenje poruka", koje je od posebnog značaja u paralelnom izračunavanju, međuprocesnoj komunikaciji i objektno orijentisanom programiranju. U ovim slučajevima, individualne komponente nemaju proizvoljni prenos kontrole, ali celokupna kontrola može biti preneta na komplikovaniji način.

Varijacije na temu

Postoji mnoštvo različitih jezičkih konstrukcija pod klasom goto naredbe. U nastavku će biti opisane neke od najčešće korišćenih.

-{"Computed goto"}-

U -{Fortranu}-, -{"computed goto"}- prenosi kontrolu na neku od labela navedenih u listi, na osnovu vrednosti izraza. Na primer: goto (20,30,40) i. Ekvivalentna konstrukcija u -{C}--u je -{switch}- naredba, a u novoj verziji -{Fortrana case}- naredba je preporučena sintaksička alternativa. Programski jezik -{Basic}- koristi konstrukciju: on ... goto da postigne isti cilj.

-{"Assigned goto"}-

U Fortranu takođe postoji i varijanta takozvane -{"assigned goto"}- naredbe koja prenosi kontrolu na labelu naredbe (broj linije) koja je sačuvana u (-{assigned to}-) celobrojnoj promenljivoj. Prelaz na celobrojnu promenljivu koja nije dodeljena nijednoj liniji koda, bio je nažalost moguć, i to je bio glavni izvor grešaka koje uključuju -{"аssigned goto"}- naredbe. U -{Fortranu}-, naredba assign jedino dozvoljava dodelu linije koda koja je konstantna (već postoji) celobrojnoj promenljivoj. Međutim, bilo je moguće da se ova promenljiva slučajno tretira kao celobrojna, na primer, inkrementiranjem koje rezultira neočekivanim ponašanjem goto naredbe. Sledeći primer demonstrira ponašanje -{"assigned goto"}- kada je linija i neodređena:
    assign 200 to i
    i = i+1
    goto i ! neočekivano ponašanje
200 write(*,*) "ovo je postojeći broj linije koda" 

Nekoliko -{C}- kompajlera implementiralo je dve nestandardne -{C/C++}- ekstenzije koje se odnose na goto, predstavljene su od strane gcc-a (GNU kolekcija kompajlera). Ova ekstenzija dozvoljava da adresa labele unutar trenutne funkcije bude dobijena kao void*, koristeći unarni operator &&. Goto naredba je proširena tako da dozvoljava prenos kontrole na proizvoljni void* izraz. U dokumentaciji C kompajlera ovo profirenje odnosi se na "computed goto". Kao i u standardnom goto u C-u, i u ovoj ekstenziji dozvoljeno je da goto prenosi kontrolu samo na linije unutar trenutne funkcije. Pokušaj prenosa izvan trenutne funkcije rezultira neočekivanim ponašanjem.

Podrške u programskim jezicima
Mnogi jezici podržavaju goto naredbu, a ima i onih koji je ne podržavaju. U Javi, goto je rezervisana rec ali je neupotrebljiva, s obzirom da kompilacioni file.class generiše goto i labele. -{Python}- ne podržava upotrebu goto naredbe, dok -{PHP}- nije podržavao goto sve do verzije 5.3. U C# postoji goto naredba. Takođe, moguće je dodati -{case}- i -{default}- labele. -{Goto case}- i -{Goto default}- često se koriste da zamene -{"fall-through"}- koji -{C#}- zabranjuje. -{C}- ima goto i obično se koristi u različitim idiomima, kao što je gore opisano.

Videti još
 Virtuelna memorija
 Kompilator
 Optimizacija kompilatora
 Interpretator
 Optimizacija petlje

Reference

Literatura 

 
 

Контрола тока
Едсгер Дајкстра