Laboratorija za računarsku tehniku

Softverske teme => Programiranja => C => Temu započeo: gagi 09.11.2010, 13:03

Naslov: goto
Poruka od: gagi 09.11.2010, 13:03
U svim knjigama o C-u negde na samom početku stoji rečenica koja je uglavnom ispisana velikim, zadebljanim slovima - "izbegavajte korišćenje naredbe goto". Kao argument se navodi složena i zamršena struktura koju preterano korišćenje naredbe goto proizvodi ("špageti" kod, "kengurov" kod). Svi tekstovi vezani za struktuirano programiranje su takodje preporučivali isto, čak se na samom početku ere struktuiranog programiranja vodio "slučaj" protiv korišćenja ove naredbe (" A Case Against the Goto Statement", članak koji je napisao Dijkstra a koji je poznatiji kao "Goto Statement Considered Harmful").

Zaista ne treba opisivati koliko sam se začudio kada sam u zaista kvalitetno napisanom kodu naleteo na ovu naredbu. Pomislih da je ovo izolovan slučaj i pošto sam bio u priličnoj gužvi nisam se pozabavio ozbiljno ovim pitanjem. Kada sam ponovo naleteo na ovu istu naredbu u jednom BSP-u prilično sam se zainteresovao. Na kraju, nakon dosta čitanja na ovu temu evo zaključka - goto naredba u nekim slučajevima ne samo da ne treba izbegavati već definitivno predstavlja najbolje moguće rešenje. Ako se pažljivo koristi, ona u pojedinim situacijama doprinosi poboljšanju brzine izvršavanja i smanjuje veličinu koda. Upravo zato su je koristili u kodu na koji sam naleteo.
Naslov: Re: goto
Poruka od: Siniša Ranđić 09.11.2010, 13:23
Da đavo nije sasvim crn, tj. da se i sa GOTO naredbom mogu pisati strukturirani programi smatrali su mnogi autori. Jedan od gurua savremenog računarstva Donald Knuth je napisao članak pod naslovom "Structured Programming with go to Statement", koji se može preuzeti na adresi http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf.
Naslov: Re: goto
Poruka od: Marko Аcović 09.11.2010, 13:57
Slazem se sa obe izjave. U principu, treba je izbegavati ali kad ne postoji bolje resenje, zasto da se ne iskoristi. Trebamo biti svesni zasto smo u datom trenutku odabrali goto i sta mogu da budu posledice tog izbora.
Naslov: Re: goto
Poruka od: gagi 09.11.2010, 14:49
Evo jedne izuzetne diskusije na ovu temu u kojoj je ucestvovao jos jedan od gurua savremenog računarstva, Linus Torvald
http://kerneltrap.org/node/553/2131
Primer koda koji intezivno koristi ovu naredbu se može skinuti na http://www.sics.se/~adam/uip/index.php/Download. Reč je o implementacij TCP/IP steka namenjenoj platformama sa malo resursa (može da trči čak i na osmobitnim kontrolerima). Jedan od mehanizama obaranja veličine koda je upravo naredba goto. Da citiram autora:
uIP is a small implementation of the IP, UDP and TCP protocols (aswell as some basic ICMP stuff). The implementation couples the IP, UDP, TCP and the application layers very tightly. To keep the size of the compiled code down, this code frequently uses the goto statement. While it would be possible to break the uip_process() function into many smaller functions, this would increase the code size because of the overhead of parameter passing and the fact that the optimier would not be as efficient.


Naslov: Re: goto
Poruka od: vukasheen 09.11.2010, 16:57
Interesantna tema,

efikasnost vs. preglednost, sigurnost
trošenje vremena na izradu koda ili gubitak performansi, što povlači i veću potrošnju energije ( ekologija teba broj 1. :D).

Java ima jedan kompromis što se toga tiče, labele.
Petlje se obeležavaju labelama a posle se može napustiti odgovarajuća petlja pozivanjem break labela ili continue labela.
Ovo ima smisla u višestruko ugnježdenim petljama. Predpostavljam da većina vas to zna ali da se zabeleži možda nekome zatreba
Evo i primera: http://www.wellho.net/resources/ex.php4?item=j704/Bills.java
Naslov: Re: goto
Poruka od: marjan 09.11.2010, 22:23
Mislim da je preporuka o nekorišćenju goto sasvim na mestu - upravo tamo gde se daje i za cilj joj je da kod programera indukuje naviku pisanja jasnog i strukturiranog koda, pa se onda ovakvi specijalni slučajevi javljaju kao izuzetak koji potvrđuje pravilo. Čini mi se da Liberty (ili tako neki autor) baš navodi da mu je goto bio (bilo?) odlično rešenje svega par puta u životu.
Ako idemo na optimizaciju (opet u nekim slučajevima) ili dublje ka low-level programiranju, goto je očigledno koristan put - pa i JMP je sasvim normalna naredba u asembleru.
Naslov: Re: goto
Poruka od: holodoc 10.11.2010, 00:29
Citat: vukasheen  09.11.2010, 16:57
Interesantna tema,

efikasnost vs. preglednost, sigurnost
trošenje vremena na izradu koda ili gubitak performansi, što povlači i veću potrošnju energije ( ekologija teba broj 1. :D).

Java ima jedan kompromis što se toga tiče, labele.
Petlje se obeležavaju labelama a posle se može napustiti odgovarajuća petlja pozivanjem break labela ili continue labela.
Ovo ima smisla u višestruko ugnježdenim petljama. Predpostavljam da većina vas to zna ali da se zabeleži možda nekome zatreba
Evo i primera: http://www.wellho.net/resources/ex.php4?item=j704/Bills.java
Nisu labele Java ekskluzivitet :) Čak štaviše labele su ubedljivo jedan od najstarijih izuma programiranja koji se koristio još u vreme BASIC-a. Možda se neko ovde još uvek seća da je za originalan BASIC bilo karakteristično da mu svaka linija koda bude numerisana jednim brojem i to u rastućem nizu a na koji se kod mogao u bilo kom trenutku prebaciti korišćenjem komande GOTO.

Primera radi sledeći kod...
10 REM Test program
20 PRINT "HELLO WORLD!"
30 GOTO 10

Numeracija redova je upravo bila prva varijanta labela a to je izum koji sada ima pa već više od 30 i kusur godina :)

Kasnije su neke savremenije verzije BASIC-a tipa AmigaBASIC uvele mogućnost "numeracije" redova labelama na sledeći način:
POCETAK:
PRINT "HELLO WORLD"
GOTO "POCETAK"

Što se tiče continue i break one su danas sastavni deo bukvalno svakog programskog jezika. Primera radi mali broj ljudi zna da break u okviru switch petlje u stvari nije sastavni deo petlje već da je to potpuno neyavistan element koji može da se izostavi i da se tako realizuje algoritam "propadanja" switch petlje :)
switch(vrednost){
    case 1 :
        // Kod za skucaj 1...
        break;
    case 2 :
        // Kod za vrednost 2...
    case 3 :
        // I ovo ima da se izvrsi ukoliko je vrednost 2...
    default :
        // Default grana...
}

continue je isto tako poprilično standardan u algoritmima za prevremeni izlazak iz petlje.
include <stdio.h>
#include <stdlib.h>

int i, j, suma = 0 ;

int main(){
for(i=0; i < 10; i++){
        for(j = 0; j < 10; j++){
                if(i > 5){
                        continue;
                }
                suma += j;
        }
}
printf("%d\n",suma);
return EXIT_SUCCESS;
}

Naslov: Re: goto
Poruka od: Marko Аcović 10.11.2010, 00:36
Samo mala korekcija, ako dozvoljavas :)
Naslov: Re: goto
Poruka od: gagi 10.11.2010, 00:57
Za one koji su bili lenji da procitaju moje linkove, izdvojicu jedan post Linusa Torvalda u kome on iznosi neke argumente u prilog goto naredbe. Ovakve stvari su upravo ono sto me je iznenadilo jer su donekle narusile moje poimanje proceduralnog programiranja i redefinisalo moje stavove. Zaista, na prvu loptu (ili na prvi goto) sam pomislio da je pisao neki amater i verovao sam da me ceka "spaghetti a la carbonara" jer svi su tako govorili. Naisao sam na zaista elegantna i mocna resenja koja su kod ucinila lepsim, brzim i manjim a to je nesto cemu po mom skromnom misljenju treba stalno teziti.

From: Linus Torvalds
Subject: Re: any chance of 2.6.0-test*?
Date:    Sun, 12 Jan 2003 12:22:26 -0800 (PST)

On Sun, 12 Jan 2003, Rob Wilkens wrote:
>
> However, I have always been taught, and have always believed that
> "goto"s are inherently evil.  They are the creators of spaghetti code

No, you've been brainwashed by CS people who thought that Niklaus Wirth
actually knew what he was talking about. He didn't. He doesn't have a
frigging clue.

> (you start reading through the code to understand it (months or years
> after its written), and suddenly you jump to somewhere totally
> unrelated, and then jump somewhere else backwards, and it all gets ugly
> quickly).  This makes later debugging of code total hell. 

Any if-statement is a goto. As are all structured loops.

Ans sometimes structure is good. When it's good, you should use it.

And sometimes structure is _bad_, and gets into the way, and using a
"goto" is just much clearer.

For example, it is quite common to have conditionals THAT DO NOT NEST.

In which case you have two possibilities

- use goto, and be happy, since it doesn't enforce nesting

   This makes the code _more_ readable, since the code just does what
   the algorithm says it should do.

- duplicate the code, and rewrite it in a nesting form so that you can
   use the structured jumps.

   This often makes the code much LESS readable, harder to maintain,
   and bigger.

The Pascal language is a prime example of the latter problem. Because it
doesn't have a "break" statement, loops in (traditional) Pascal end up
often looking like total shit, because you have to add totally arbitrary
logic to say "I'm done now".

      Linus
Naslov: Re: goto
Poruka od: holodoc 10.11.2010, 01:40
Nemam nameru da ocrnjujem čoveka ali opšte je poznata činjenica da Torvalds danas prevashodno živi od slave koju je stekao u svojim studentskim danima i potrebe da se stalno utrkuje sa Stallmanom ko je odmah prvi do Pape :)

Povodom nekih od njegovih izjava navedenih u prethodnom postu mogu samo da kažem da imam osećaj da čovek i dalje misli da su kompajleri ostali na nivou na kojem su bili u vreme dok je on studirao :) Kompajleri a i tehnologija razvoja softvera su se u poslednjih nekoliko godina toliko razvile da su svi ovi pokušaji mikrooptimizacije i traženja litra rakije u buretu vina čist senzacionalizam  B-) Baš zato što većina kompajlera danas potpuno ignoriše način na koji je kod pisan i što kompajleri automatski biraju način optimizacije koda da bi postigli bolje rezultate. Drugim rečima, raditi ovakav tip mikrooptimizacije koda čisto zbog koda i navodnog povećanja performansi je u današnjim uslovima skoro potpuno gubljenje vremena jer opcije pri pisanju koda nisu tu da bi olakšale posao kompajlerima već onima koji pišu kod :)

To opet ne znači da se prema resursima mašine koja izvršava krajnji kod treba odnositi kao svinja prema masnom džaku :) Dakle poptuno podržavam optimizacije koje imaju veliki koeficijent odnosa dobijenih performansi i uloženog vremena ali ovakve tipove gubljenja vremena...Hm... Pa ne baš   >:D<
Naslov: Re: goto
Poruka od: holodoc 10.11.2010, 01:42
Citat: marko_gm  10.11.2010, 00:36
Samo mala korekcija, ako dozvoljavas :)

  • break iskace iz petlje (iz najdublje petlje ako ima vise ugnezdjenih petlji)
  • continue ide na kraj petlje, tj. prelazi na sledecu iteraciju
Istina nisam baš upotrebio precizne definicije ali cenim da je poruka jasna bila iz koda :)
Naslov: Re: goto
Poruka od: gagi 10.11.2010, 11:47
Citat: holodoc  10.11.2010, 01:40

Povodom nekih od njegovih izjava navedenih u prethodnom postu mogu samo da kažem da imam osećaj da čovek i dalje misli da su kompajleri ostali na nivou na kojem su bili u vreme dok je on studirao :) Kompajleri a i tehnologija razvoja softvera su se u poslednjih nekoliko godina toliko razvile da su svi ovi pokušaji mikrooptimizacije i traženja litra rakije u buretu vina čist senzacionalizam  B-) Baš zato što većina kompajlera danas potpuno ignoriše način na koji je kod pisan i što kompajleri automatski biraju način optimizacije koda da bi postigli bolje rezultate.

Mislim da grešiš jer razmišljaš kroz prizmu desktop i serverskih mašina. U tim sferama sve ovo i nije tako bitno jer je dodatni gigabajt memorije za jedan ili dva servera jeftiniji od jednog programerskog sata pa se ne isplati razmišljati o takvim stvarima. Ti uvek možeš da proširiš tvoj server tako da te baš briga kakav kod pravi Java, C# ili PHP. Sa druge strane, taj isti kernel se nalazi na gomili platformi skromnih hardverskih mogućnosti. Kada se tvoja aplikacija izvršava na takvoj platformi, onda ti je VEOMA bitno kako je kod pisan i šta će kompajler generisati jer nemaš mogućnost kupovine dodatnih resursa (jer je povećane od jednog dolara u seriji od 5 miliona mnogo i to ti niko neće dozvoliti pa ćeš i te kako da se zamlaćuješ ovakvim gubljenjem vremena).
Naslov: Re: goto
Poruka od: marjan 10.11.2010, 14:32
Super je sve to, ali nazivati Wirtha neznalicom je... hm, malo preterano, ne?
Naslov: Re: goto
Poruka od: holodoc 10.11.2010, 17:00
Citat: gagi44  10.11.2010, 11:47Mislim da grešiš jer razmišljaš kroz prizmu desktop i serverskih mašina. U tim sferama sve ovo i nije tako bitno jer je dodatni gigabajt memorije za jedan ili dva servera jeftiniji od jednog programerskog sata pa se ne isplati razmišljati o takvim stvarima. Ti uvek možeš da proširiš tvoj server tako da te baš briga kakav kod pravi Java, C# ili PHP. Sa druge strane, taj isti kernel se nalazi na gomili platformi skromnih hardverskih mogućnosti. Kada se tvoja aplikacija izvršava na takvoj platformi, onda ti je VEOMA bitno kako je kod pisan i šta će kompajler generisati jer nemaš mogućnost kupovine dodatnih resursa (jer je povećane od jednog dolara u seriji od 5 miliona mnogo i to ti niko neće dozvoliti pa ćeš i te kako da se zamlaćuješ ovakvim gubljenjem vremena).
Situacija je upravo suprotna zato što dok na zasebnoj mašini imaš malu konkurentnost (često samo jedan korisnik) na serverskim mašinama je konkurentnost neuporedivo veća i meri se neretko i hiljadama zahteva u minuti a svaki zahtev je minimlano jedan thread ili proces :)

Veruj mi poslednjih nekoliko godina bavim se isključivo razvojem web aplikacija i upgrade hardvera je poslednja stvar na koju će se klijent odlučiti ako ima odvojene dedicated servere a da ne pričam o prelasku na skuplji tarifni paket na nekom VPS ili ne daj bože shared hostingu za koje u slučaju intenzivnijih aplikacija troškove neće podmiriti ni prodaja svih zdravih organa koje poseduješ [-( Za to uglavnom postoji nekoliko razloga:

1) Imaš tu "sreću" da klijent dovoljno dobro ignoriše realne zahteve  aplikacije i pravda se "neopravdanim troškovima za nešto što radi i sad kako treba".
2) Serveri ne koriste baš tako jeftinu memoriju jer zahtevaju izrazito skupu ECC memoriju od kvalitetnih proizvođača tako da pločica po pločica uskoro ispadne čestomesečna plata programera a i jednog dana će ponestati slotova za pločice :)
3) Downtime na bilo kom serveru koji nije deo clustera znači gubljenje vremena i nedostupnost web aplikacije a to u prevodu za klijenta znači gubitak vremena i novca tako da se samo sat vremena nefunkcionisanja sajta na prilično posećenim sajtovima i web aplikacijama smatra katastrofom :D

Ovo poslednje je možda jedna od najbitnijih stavki i pokušaću da ilustrujem na ličnom iskustvu. Naime sećam se da sam nakon neke vanredne situacije na serverima jednog od klijenata morao privremeno da koristim servis koji se nalazi na serveru CSL laboratorije (u pitanju je GeoIP aplikacija na http://csl.tfc.kg.ac.rs/~brezanac/geoip/) na koji sam ja posle sređivanja problema poptuno zaboravio. Nekoliko dana kasnije klijent se javlja i paniči kako su svi njegovi sajtovi (ukupno 4 komada) offline i da ne može da im se pristupi. Za njega koji čak 90% prihoda od krajnje unosne industrije zasniva na online prodaji i negovanju svoje baze vernih kupaca to je katastrofa naravno :) A zbog čega? Ispostavilo se da se toga dana na TFC-u zapalila razvodna kutija pa je struja bila isključena na celom fakultetu :I Kompletna priča se završila skoro četvoročasovnim offline statusom svih sajtova i poprilično velikim gubitkom zarade klijenta tog dana tako da od tada strogo vodim računa da čak i backup rešenja za hitne situacije imaju backup :)

Sa druge strane što se tiče pojedinačnih mašina sa malom konkurentnošću (tipično jedan korisnik) one ne gube mnogo na performansama kada se recimo prebaci maksimalna količna memorije koju računar poseduje jer je čak i virtuelna memorija (page file) dovoljno brz da odradi zahteve sa veoma malim kašnjenjem. Sa druge strane kada server prebaci memorijsko ograničenje u situaciji sa velikom konkurentnošću isti plaća velike penale zbog nesposobnosti CPU-a da isprati sve manipulacije nad virtuelnom memorijom i server se jednostavno guši.

Da skratim priču... Ja nigde nisam naveo da je optimizacija loša stvar. Čak štaviše mogu slobodno da kažem za sebe da sam poprilični paćenik kada je optimizacija u pitanju ali i da pokušavam da se odviknem od navike da baš sve mora da optimizujem na šta naletim jer se takva rabota jednostavno ne isplate kada se uporedi dodatno uloženo vreme i dobijeni rezultat. Takođe, jedna je stvar ako neko piše aplikacije za svoje potrebe pa želi da mu kod bude što je moguće optimizovaniji (recimo kad radi na nekom svom projektu) i nema zadate rokove ali u svakodnevnim uslovima kad ti klijenti dahću za vratom i traže da vide rezultate u roku od odma' ne možeš da razmišljaš o takvim stvarima :)

Ja ću samo navesti da lično ne volim niti podržavam korišćenje bezuslovnih skokova jer isto tako kao što Torvalds kaže da je svaki "if" u stvari "goto" i svaki "goto" je jedan "if" :) Kako? Jednostavno. Veoma su retke situacije da je sam bezuslovni skok potpuno bezuslovan već svakom skoku uvek prethodi neki uslov. U switch petljama (uslovno rečeno) break-u uvek prethodi neki case i ima mali milion sličnih primera. Zašto onda komplikovati kod i činiti ga nečitljivim? Zašto veštački prekidati tokove akcija?

Inače lično bih voleo da vidim algoritam koji ne može efikasno da se realizuje isključivo putem koda bez bezuslovnih skokova :)
Naslov: Re: goto
Poruka od: gagi 10.11.2010, 22:11
Citat: holodoc  10.11.2010, 17:00
Ovo poslednje je možda jedna od najbitnijih stavki i pokušaću da ilustrujem na ličnom iskustvu. Naime sećam se da sam nakon neke vanredne situacije na serverima jednog od klijenata morao privremeno da koristim servis koji se nalazi na serveru CSL laboratorije (u pitanju je GeoIP aplikacija na http://csl.tfc.kg.ac.rs/~brezanac/geoip/) na koji sam ja posle sređivanja problema poptuno zaboravio. Nekoliko dana kasnije klijent se javlja i paniči kako su svi njegovi sajtovi (ukupno 4 komada) offline i da ne može da im se pristupi. Za njega koji čak 90% prihoda od krajnje unosne industrije zasniva na online prodaji i negovanju svoje baze vernih kupaca to je katastrofa naravno :) A zbog čega? Ispostavilo se da se toga dana na TFC-u zapalila razvodna kutija pa je struja bila isključena na celom fakultetu :I Kompletna priča se završila skoro četvoročasovnim offline statusom svih sajtova i poprilično velikim gubitkom zarade klijenta tog dana tako da od tada strogo vodim računa da čak i backup rešenja za hitne situacije imaju backup :)

Sa druge strane što se tiče pojedinačnih mašina sa malom konkurentnošću (tipično jedan korisnik) one ne gube mnogo na performansama kada se recimo prebaci maksimalna količna memorije koju računar poseduje jer je čak i virtuelna memorija (page file) dovoljno brz da odradi zahteve sa veoma malim kašnjenjem. Sa druge strane kada server prebaci memorijsko ograničenje u situaciji sa velikom konkurentnošću isti plaća velike penale zbog nesposobnosti CPU-a da isprati sve manipulacije nad virtuelnom memorijom i server se jednostavno guši.



Iz ovog zaključujemo da ne pričamo baš o istim stvarima. Ti isključivo razmišljaš o desktop računaru i korisniku koji sedi za tastaturom. Pored računara čiji si vlasnik ti, verovatno i tvoja veš-mašina, automobil i televizor imaju  svoje"računare" a ako imaju sreće da su novije generacije možda ga imaju i toster i četkica za zube. :) Tu se i te kako vodi računa o resursima i brzini izvršavanja, posebno u domenu hard real-rime sistema. Zaista bih voleo da ne moram da se zamlaćujem ovakvim stvarima, ali na žalost moram.

Ono što sam želeo da istaknem jeste da sam u praksi naišao na nešto što odudara od onog što smo učili u knjigama i da sam malo promenio razmišljanje u pogledu proceduralnog programiranja. Jednostavno,  postoje slučajevi u kojima goto čini kod preglednijim od bilo kog drugog rešenja a to je ono što mi ranije ne bi palo ni na kraj pameti. Uz to, mogu znatno da unapredim performanse a to mi je dovoljan razlog da u svojim rešenjima žrtvujem preglednost koda jer na raspolaganju nemam mnogo resursa i ne mogu ih proširiti. Možda grešim i treba da odbacim ovo rešenje tako da bih voleo da čujem argumente koji su bazirani na konkretnim primerima.
Naslov: Re: goto
Poruka od: holodoc 10.11.2010, 23:22
Citat: gagi44  10.11.2010, 22:11Iz ovog zaključujemo da ne pričamo baš o istim stvarima. Ti isključivo razmišljaš o desktop računaru i korisniku koji sedi za tastaturom. Pored računara čiji si vlasnik ti, verovatno i tvoja veš-mašina, automobil i televizor imaju  svoje"računare" a ako imaju sreće da su novije generacije možda ga imaju i toster i četkica za zube. :) Tu se i te kako vodi računa o resursima i brzini izvršavanja, posebno u domenu hard real-rime sistema. Zaista bih voleo da ne moram da se zamlaćujem ovakvim stvarima, ali na žalost moram.
Zaista ne znam odakle si zaključio da ja "isključivo razmišljam o desktop računarima i korisnicima za tastaturom" kad ja sve vreme govorim u kontekstu razvoja a ne korišćenja softvera :) Što se tiče pomenutih veš mašina, automobila i televizora to je već posebna sfera programiranja više orijentisana ka hardveru čiji je zadatak uglavnom da realizuje mnogo jednostavnije algoritme od onih koji se koriste u klasičnoj softverskoj industriji u pravom smislu te reči (desktop, web i druge namenske aplikacije). Međutim za detalje oko optimizacije koda za programiranje mikroelektronike moraćeš ipak da konsultuješ nekoga ko se bavi time pošto se ja bavim isključivo klasičnim razvojem softvera ;)
Citat: gagi44  10.11.2010, 22:11Ono što sam želeo da istaknem jeste da sam u praksi naišao na nešto što odudara od onog što smo učili u knjigama i da sam malo promenio razmišljanje u pogledu proceduralnog programiranja.
Pa pazi, sasvim je normalno da se praksa razlikuje od teorije. Zato se i uče ili stiču odvojeno :D
Citat: gagi44  10.11.2010, 22:11Jednostavno,  postoje slučajevi u kojima goto čini kod preglednijim od bilo kog drugog rešenja a to je ono što mi ranije ne bi palo ni na kraj pameti. Uz to, mogu znatno da unapredim performanse a to mi je dovoljan razlog da u svojim rešenjima žrtvujem preglednost koda jer na raspolaganju nemam mnogo resursa i ne mogu ih proširiti. Možda grešim i treba da odbacim ovo rešenje tako da bih voleo da čujem argumente koji su bazirani na konkretnim primerima.
Možeš li da daš neki konkretan primer koda ili algoritma koji ne može da se reši ni na koji drugi način osim korišćenja bezuslovnih skokova i obrazloženje zbog čega misliš da je kod koji sadrži bezuslovne skokove pregledniji? :) Ja ću argumentaciju svog stanovišta započeti predlogom da napraviš anketu među iskusnijim programerima (jezik i platforma nisu bitni) i priupitaš ih šta misle o bezuslovnim skokovima (ukoliko su ih uopšte ikada koristili :) ) ili da bar pročitaš jedan članak (u stvari to je deo poglavlja a knjigu negde imam već u elektronskom obliku) iz knjige koja se da kažemo malkice ozbiljnije bavi ovom problematikom. Pre nego prokomentarišeš članak obrati pažnju na to da se isti odnosi gotovo isključivo na jezike koji nemaju sistem prekida kontrole tokova i da članak čak pokušava na neki način da odbrani ideju korišćenja bezuslovnih skokova u određenim situacijama. Dakle jedini pravi bastion obožavalaca tog pristupa nalazi se u redovima za današnje pojmove već antikviteta od programa tipa Pascal-a itd. (ne mogu da se setim da li beše FORTRAN ima bilo kakav ekvivalent prekida kontrole toka.).
Naslov: Re: goto
Poruka od: gagi 11.11.2010, 01:12
Pričao si o serveru a zatim o jednokorisničkom sistemu koji ne gubi na performansama (???) kada se prekorači memorija jer postoji virtuelna memorija. Iz toga zaključih da su to uglavnom desktop računari. U linkovima koje sam prosledio se govorilo i o preglednijem kodu. Možeš se uveriti u linuks kernelu, Freescale-ovim BSP paketima a da ne bi gubio vreme ja ti dajem odmah jedan link koji predstavlja dobar primer
http://www.cprogramming.com/tutorial/goto.html
Mislim da je ovde jasno da je goto bolje rešenje i da je kod pregledniji. Na pitanje da li mogu da ti dam algoritam koji nije moguće rešiti bez goto mogu samo da odgovorim novim pitanjem - Da li postoji neki algoritam koji nije moguće napisati na više načina? Naravno, samo jedno rešenje je optimalno a u gore navedenom primeru je jasno koje. Ozbiljan članak je dao profesor, mislim da autor ima dovoljnu težinu. Liberty (Marjan ga je spomenuo) reče da mu je bilo potrebno svega par puta u životu dakle zaključuje se da ipak ni on nije protivnik a i on ima neki ugled koliko ja znam ( i iskusan je programer). Teorija i praksa po meni nisu i nikako ne mogu biti odvojeni procesi, već je to jedan proces koji u našem primeru mora biti kontinualan. Ovde doduše ne mogu da se ne setim jedne šale koja glasi:  "In theory, theory and practice are the same. In practice, they are not."  :)

Takođe želim da se osvrnem i na priču o jednostavnijim algoritmima i klasičnoj softverskoj industriji. Nije mi baš jasno šta je to klasičan softver a šta je to "ono ostalo". Pisao sam neke aplikacije koje su se izvršavale dva dana na izuzetno močnom serveru, probao sam i da pišem one koje se izvšavaju u deliću sekunde na sistemu sa par hiljada bajtova ram memorije a malo nešto baratam i sa ovim klasičnim softverom i ne mogu da kažem šta je lakše a šta teže. Svaki ima svoju težinu, svaki nosi neke posebne izazove i svaki ima svoju posebnu draž.  Ja imam tezu da svako ko radi neku aplikaciju mora savršeno da poznaje alate koje koristi (programski jezici, tehnike programiranja, razvojna okruženja i slično) i  mora odlično da poznaje oblast kojoj je aplikacija namenjena (na primer ako radi obradu signala koja stiže od digitalnog stetoskopa mora da zna šta traži u tom signalu, što znači da mora da poznaje malo medicine). Kod "mikroelektronike" moraš još da poznaješ i malo elektronike. Sve pojave u okruženju kod ovakvih sistema se odvijaju u realnom vremenu i ne smeš sebi dozvoliti da ih ispustiš u nekim situacijama a resursi su ti jako skromni. Kada nastane bug tokom testiranja na terenu teško je pronaći uzrok jer je teško reprodukovati tu situaciju sa terena u laboratoriji  a greška može da nastane kako zbog greške programera tako i zbog nekih uvrnutih razloga kao što je stalno uključivanje hidrofora u obližnjoj zgradi. Nema moćnih alata za ubijanje buba koje su ti na raspolaganja, ne možeš da zabodeš brejk. Dakle daleko više nepoznatih faktora je u igri što ti zagorčava život. Algoritmi mogu biti jednostavni na svim platformama, ali mogu biti i izuzetno komplikovani bez obzira na platformu. Verovatno su algoritmi koji su smešteni u jednu ploču ne veću od grafičke a koja obrađuje nekoliko telefonskih poziva daleko komplikovaniji od onih koje smo svi zajedno ikad pisali. I podela na hardver i softver nije kruta i kao što neko reče "hardver je okamenjen softver". Ono što je softver današnjice može biti hardver sutrašnjice i obrnuto tako da je svako programiranje pomalo okrenuto ka hardveru.  :)
Naslov: Re: goto
Poruka od: holodoc 11.11.2010, 01:55
Citat: gagi44  11.11.2010, 01:12Pričao si o serveru a zatim o jednokorisničkom sistemu koji ne gubi na performansama (???) kada se prekorači memorija jer postoji virtuelna memorija. Iz toga zaključih da su to uglavnom desktop računari. U linkovima koje sam prosledio se govorilo i o preglednijem kodu.
Nadam se da nemaš nameru da kažeš da jedan od ta dva računara ima virtuelnu memoriju a drugi ne jer ako je tako nadam se da si već položio Arhitekturu računara. U suprotnom si obr'o bostan ako profesor Ranđić ovo pročita :D

Mislim danas ćeš teško uspeti da nađeš operativni sistem koji ne koristi virtuelnu memoriju pošto većina koristi multitasking kernel. U prevodu i server i jednokorisnički sistem koje sam naveo u svom postu koriste virtuelnu memoriju bez obzira na to što možda implementiraju virtuelnu memoriju na drugačije načine. Na Windows baziranim sistemima virtuelnu memoriju čini raspoloživi RAM u kombinaciji sa tzv. page fajlovima dok se na UNIX-olikim sistemima virtuelna memorija najčešće formira kombinacijom RAM memorije i swap particija.

Ostatak poruke i posebno ovaj primer za koji si dao link ću morati da proučim detaljnije malo kasnije ili eventualno u toku sutrašnjeg dana pošto imam još nekih sat-dva da završim neki posao a već sam na izdisaju sa koncentracijom. Ne brini se neću zaboraviti ;)
Naslov: Re: goto
Poruka od: gagi 11.11.2010, 09:24
Ne, nisam mislio da jeda od ta dva rаčunara nema virtuelnu memoriju već da postoje mnogo manji sistemi kod kojih ovi mehanizmi ne postoje. Pogledaj kod pa reci da li je narušena preglednost koda i da li postoji bolje rešenje. Ubedi me.  :)
Naslov: Re: goto
Poruka od: marjan 11.11.2010, 23:30
Ih, što ste neki :\
LM, gagijev primer je u stvari primer koji navode i K&R u svom klasiku.
Na kraju, kažu:
Citat
With a few exceptions like thosed cited  here, code that relies on goto statement is generally harder to understand and to maintain that code without gotos. although wea re not dogmatic about the matter, it does seems that goto statements should be used rarely, if at all.

-----

Hej, kako to da sam odmah po slanju poruke imao Utisak +1?? Mnogo pametan SMF, a? :))

Doduše, rasipa memoriju - pre neku poruku sam dobio "kilobajt" uz profil - pre sam bio bajt. LOL

goto sleep;
Naslov: Re: goto
Poruka od: gagi 12.11.2010, 11:14
Hvala Marjane, to mi je promaklo.  :) Kao u svim stvarima u životu, tako i ovde treba naći meru. Mislim da postoje primeri gde je Dijskstra u pravu, ima i oblasti gde je Knuth u pravu. Stalni sukobi poput onih Mac vs PC, Intel vs AMD, Linux vs Windows, Gibanica vs Pizza... Mogu da postavim bezbroj tema i svaka od njih će izazvati pravi mali rat i podeliti ljude u minimu dva tabora. Elem, ono što htedoh reći jeste da je istina negde u sredini, pa tako goto u malim količinama može biti pravi lek a u prevelikoj meri može postati otrov. Sve je na programeru i ipak od njegovog kvaliteta zavisi kvalitet krajnjeg rešenja (tj programa) a ne od alata koje koristi. Što reče Njegoš u rukama Mandušića Vuka svaka će puška biti ubojita. Evo i ternarni izrazi mogu biti loši:
http://csl.tfc.kg.ac.rs/forum/index.php/topic,319.0.html
Naslov: Re: goto
Poruka od: holodoc 12.11.2010, 22:18
Kasnim malo sa svojim odgovorom zbog posla koji je još uvek aktuelan tako da se unaped izvinjavam što ovoga puta neću biti u prilici da napišem kilometarski post  >:D< EDIT: Ipak se ispostavilo da je kilometarski post u pitanju  :boodala:

@gagi44
Pogledao sam ponovo stranicu za koju si dao link i mogu da kažem samo da nisi mogao da odabereš bolji primer za demonstraciju zašto su argumenti za korišćenje goto-a u stvari njegovi najveći neprijatelji :) U stvari sad kad je Marjan pomenuo da se seća te deonice koda iz K&R setio sam se da sam već vodio raspravu na ovu temu .

Pre nego što počnem sa izlaganjem moram da napomenem da je autor korišćenjem pseudo koda u stvari nesvesno (a možda i namerno :dzavo:) izbegao da demonstrira kontraindikacije koje mogu da imaju pokušaji da se uz pomoć goto komande napravi veštački sistem izuzetaka, što je upravo ono o čemu članak govori.

Prvi ozbiljan previd autor je napravio kad je kompletan "cleanup" kod smestio na jedno mesto gde će se bezuslovno pozivati nakon svake greške u kodu koja treba da ima za zadatak da kontroliše tok nakon nastanka greške i preduzme sve što treba da ne dođe do neke štete. Na prvi pogled sve izgleda super jer i exception sistem ovako funkcioniše. Postoji kod koji se proverava u try bloku pa ako dođe do exceptiona odgovarajući catch blok se pozabavi problemom. E upravo je u podebljanom tekstu poenta celog problema :dzavo: U svim programskim jezicima koji podržavaju izuzetke oni ne služe samo za lakše rešavanje situacija kad se pojave greške nego i da obezbede jednu od najbitnijih stvari kod izuzetaka - apstrakciju kroz tzv. sistem "custom exceptionsa" :) Ovim principom bezuslovnog skoka na zajednički "cleanup" kod u potpunosti je uklonjena apstrakcija koda i to je prvi korak koji garantuje prerano penzionisanje.

Krećem sa ilustracijom. Uzeću primer programera koji je dobio zadatak da napiše neko programče i koji je zbog čestog dahtanja šefa za vratom rešio da pojednostavi svoj program i iskoristi sledeću strukturu u jednoj od funkcija koja ima za cilj da radi neku složenu obradu podataka.int big_function()
{
    int ret_val = [success];
    /* do some work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
end:
    /* clean up*/
    return ret_val;
}


Programer je uspeo da na vreme završi svoj zadatak i da napiše ne baš tako složenu funkciju u kojoj se pri kraju poziva kod za "cleanup" operacije koji nije komplikovan. Dan kasnije programer dobija zadatak da proširi svoju funkciju tako da ona izgleda sad ovako:

int big_function(){
    int ret_val = [success];
    /* do some work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
end:
    /* clean up*/
    return ret_val;
}

Programer je sada prisiljen zbog velikog broja različitih ret_value vrednosti da kraj funkcije proširi sa if ili switch petljama. U idelanom slučaju kada je ret_val jednoznačno određen možda može da se koristi i switch.
int big_function()
{
    int ret_val = [success];
    /* do some work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
end:
    if(ret_val == 1){
        /* Cleaning case 1 */
    }
    if(ret_val == 2){
        /* Cleaning case 2 */
    }
    if(ret_val == 3){
        /* Cleaning case 3 */
    }
    if(ret_val == 4){
        /* Cleaning case 4 */
    }
    return ret_val;
}

Programer je srećan što je uspeo da nađe rešenje za svoj problem ali dan kasnije dobija zadatak da funkciju proširi tako da omogućava obradu ne samo jednog tipa podataka (recimo brojeva) nego i nizova struktura. Sada očigledno postoji potreba za drugom metodom čišćenja podataka ("cleanup") i programer se nalazi pred teškim problemom jer mora da pronađe način kako da koristi drugačiju metodu čišćenja za drugačije tipove podataka. Kao što je poznato C ne podražava bilo kakve oblike overloadovanja pa programer sada dolazi u nezavidnu situaciju da razmišlja o tome da kreira ili dupli set if petlji (u gornjem slučaju bi to bilo ukupno 8 if petlji za dva tipa podataka) ili da razmišlja o koraku od koga svakom iskusnom programeru trne zubi - dodavanje još jedne labele  [-(

Programer se ipak odlučuje za goto pristup i shvata da će goreti u programerskom paklu. Njegov kod sa izgleda ovako:
int big_function()
{
    int ret_val = [success];
    /* do some work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end2;
    }
    /* do some more work */
    if([error])
    {
        ret_val = [error];
        goto end2;
    }
end:
    if(ret_val == 1){
        /* Cleaning case 1 */
    }
    if(ret_val == 2){
        /* Cleaning case 2 */
    }
    if(ret_val == 3){
        /* Cleaning case 3 */
    }
    if(ret_val == 4){
        /* Cleaning case 4 */
    }
    return ret_val;
end 2:
    if(ret_val == 1){
        /* Cleaning case 1 */
    }
    if(ret_val == 2){
        /* Cleaning case 2 */
    }
    if(ret_val == 3){
        /* Cleaning case 3 */
    }
    if(ret_val == 4){
        /* Cleaning case 4 */
    }
    return ret_val;
}
Jel treba da objašnjavam šta se dešava kada trećeg dana project manager dođe i kaže da se funkcija pokazala toliko dobro da želi da omogući i obradu nekog trećeg tipa podataka (dovoljno je da kaže druge strukture) i programer bi bio lud ako sebe ne bi spasio i skočio u najbliži bunar.

U sledećem postu ću da demonstriram kako se ovakve zamke rešavaju i to na konkretnom primeru koji sam upravo iskucao.

NASTAVLJA SE >>
Naslov: Re: goto
Poruka od: holodoc 12.11.2010, 23:20
>>> NASTAVAK IZ PRETHODNOG POSTA

Prvo da postavim kod kojim hoću da demonstriram sistem kojim bi se eliminisao problem koji sam opisao u prethodnom postu a koji je vezan za bezuslovne skokove i nedostatak apstrakcije. Kod jeste malo duži ali u principu mnogo realnije dočarava relan slučaj nego pseudo-kod koji je korišćen u originalnom članku koji sam komentarisao. Nativan SMF je bez odgovarajućih plaginova malko hendikepiran kad je u pitanju prikaz koda na stranicama pa tako ako imate neki editor sa sintaksnim bojenjem možda bi bilo dobro da ceo kod prekopirate tamo da bi mogli lakše da ga pratite.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define COUNT 100
#define CRITICAL_ERROR 1701
#define STATUS_OK 0
#define ID_ASSIGNMENT_FAILED 1
#define NAMING_FAILED 2

int processJobs();
int cleanupAndReport();
int cleanupRestoreAndReport();

typedef struct {
long jobId;
char name[24];
short error;
} Job;

int main(){
int finalStatus;

finalStatus = processJobs();
printf("Howdy! The system was about to report the following status: %d!\n", finalStatus);
(finalStatus == CRITICAL_ERROR) ? printf("Additionally there was a critical error while cleaning up!") : NULL;

getchar();
return EXIT_SUCCESS;
}

int processJobs(){
int i, status;
Job jobs[COUNT];
char *namePrefix = "Name";

srand((unsigned) time(NULL));

for(i = 0; i < COUNT; i++){
status = rand()%2;
// CHECKPOINT #1
jobs[i].jobId = rand();
if(!(rand()%2)){
jobs[i].error = 1;
return cleanupAndReport(&jobs);
}

// CHECKPOINT #2
sprintf(&jobs[i].name, "%s[%d]", namePrefix, i);
if(!(rand()%2)){
jobs[i].error = 2;
return cleanupAndReport(&jobs);
}

// CHECKPOINT #3
if(!(rand()%2)){
jobs[i].error = 3;
return cleanupRestoreAndReport(&jobs, i);
}
}

return 0;
}

int cleanupAndReport(Job *failedJob){
int status = STATUS_OK;

printf("Entered cleanupAndReport!\n");

switch(failedJob->error){
case 1 :
// CLEANING #1
break;
case 2 :
// CLEANING #2 - FATAL EXCEPTION!
status = CRITICAL_ERROR;
break;
default :
// DEFAULT
status = 1;
;
}
return status;
}

int cleanupRestoreAndReport(Job *failedJob, int failedAt){
// CLEANING AND RESTORING
printf("Entered cleanupRestoreAndReport and handling failure at %d!\n", failedAt);
return 0;
}

Cilj ovog koda je da demonstrira obradu potpuno proizvoljnih struktura i to tako da u slučaju da dođe do greške kompletna aplikacija sanira sve potencijalne probleme i operativnom sistemu vrati odgovarajući kodi rezultat.

Postoje tri funkcije:
a main() je iskorišćena samo kao supervizor procesa i služi isključivo da operativnom sistemu vrati status obrade (mogao je i kompletan kod iz processJobs da se smesti u main() ali nije zbog jedne finese na kraju). Idem redom sa objašnjenjem koda.

Na početku koda se vrše standardna učitavanja zaglavlja i definisanje / deklarisanje konstantni u okviru preprocesorskih direktiva. Tu nema ničeg spornog.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define COUNT 100
#define CRITICAL_ERROR 1701
#define STATUS_OK 0
#define ID_ASSIGNMENT_FAILED 1
#define NAMING_FAILED 2

Zatim se definišu prototipovi funkcija
int processJobs();
int cleanupAndReport();
int cleanupRestoreAndReport();

i struktura koja ima za cilj da emulira realan slučaj strukturiranih podataka - nešto tipa objekta.
typedef struct {
long jobId;
char name[24];
short error;
} Job;

Naime, dve stvari su karakterističen za C kod:
Zato sam ovde izabrao strukturu da emulira objekat ali nisam hteo nepotrebno da komplikujem kod da koristim pokazivače na pokazivače i sl. C drangulije koje penziju znače :D

Main definiše neke početne stvari a zatim poziva processJobs funkciju čiji je zadatak da u okviru niza jobs smesti COUNT (u ovom slučaju 100) elemenata tipa Jobs strukture.

Funkcija kreće sa kreiranjem prvog elementa u nizu a zatim kreću operacije sa onim ešto bi bio ekvivalent onoj liniji "/* do some work */" u primeru od kojeg je diskusija počela. Tu se prvom elementu jednostavno postavlja vrednost jobId polja koja je nasumična.
for(i = 0; i < COUNT; i++){
// CHECKPOINT #1
jobs[i].jobId = rand();

U sledećoj liniji se proverava da kojim slučajem nije došlo do greške u toku prvog posla. Ovo je u suštini veštačka simulacija pojave greške jer bi u realnim uslovima detekcija greške direktno zavisila od rezultata prvog posla. Ovde se jednostavno koristi linija
if(!(rand()%2)){
da bi se simuliralo nasumično otkazivanje koda (kod će na toj lokaciji simulirati grešku za svaki nasumični broj koji je paran).

Ukoliko dođe do greške automatski se poziva funkcija cleanupAndrestore() kojoj se prosleđuje direktna referenca na ceo niz sa elementima struktura pri čemu ako je potrebno funkciji bez problema mogu da se proslede i reference na neku od lokalnih promenjljivih. Ono što je bitno kod ove strukture je da se poziv na funkciju cleanupAndReport() radi sa linije koja počinje sa return pa se tako obezbeđuje sistem kojim se rezultat čišćenja prosleđuje hipervizor funkciji (ovde je to main()) Znači rešili smo usput još jedan problem a to je da imamo sistem putem kojeg u slučaju da dođe do problema u samoj funkciji za čišćenje (da ga nazovemo "eksepš eksepšena" :whistle2:) možemo da obavestimo hipervizora koji nadgleda ceo proces da se nešto nije odigralo kako treba pa čak i da primenimo neku meru za rešavanje tog problama u samom hipervizoru, što je odlična stvar  :> "Eksepšn esepšena" je simuliran u switch petlji funkcije cleanupAndReport za slučaj greške 2 u processJob funkciji a kad se u tom slučaju pojavi neki kritičan izuzetak koji se simulira postavljanjem vrednosti promenjljive status na CRITICAL_ERROR.

Dakle čak i da se u potpuno apstraktnoj rutini za čišćenje koda pojavi problem postoji način da se ta informacija prosledi funkciji koja ima ultimativnu reč u rešavanju problema (pa makar to bilo i amputacijom nogu i ruku koda :D) Ako kompajlirate ovaj kod što sam dao videćete da se u određenim trenucima štampa kod 1701 koji indikuje baš to stanje pojave problema u rutini za čišćenje. Da ne bude zabune ovo sa prosleđivanjem koda nije osnovna poenta cele priče već apstrakcija tj. mogućnost da korisnik bude uvek u mogućnosti da bira kome će proslediti zadatak da reši čišćenje i sa kojim parametrima.

A kako se ovo tačno razlikuje od jednostavnog postavljanja gomile petlji pri dnu jedinstvene funkcije? Upravo u tome što kada šef dođe sutra i kaže da želi da funkcija processJobs bude u stanju da obradi i strukturu koja opisuje vanzemaljace koji još uvek čekaju na izdavanje pasoša u loklanoj opštini ne treba čupati kosu zbog toga što se kompletan proces regulisanja izuzetaka sveo na rutinu koja je do tada čistila đubre nakon obrade podataka jobs niza o kome sam pričao. Jednostavno kompletan proces obrade preuzima funkcija cleanupRestoreAndReport(). Na stranu to što apstrakcija obezbeđena na ovaj način omogućava da i spisak argumenata koji se prosleđuju funkciji za čišćenje bude potpuno proizvoljan i da ne mora da se koristi mali milion petlji za kontrolu tokova da bi se pre samog čišćenja prokontrolisalo šta treba da se čisti :) Po kojoj ceni? Ceni jednog dodatnog pozivanja funkcije koja se poziva samo jednom :)

Šta smo izgubili a šta smo dobili ovim pristupom?

1) Izgubili smo priliku da koristimo goto i zbog toga nam je jako žao :)
2) Izgubili smo priliku da veštačkim pokušajem simulacije sistema izuzetaka, kojim se kompletan blok za rešavanje izuzetka smešta na kraj funkcije, budemo prisiljeni da svakom krupnijom izmenom funkcije napišemo i  beskonačan broj linija za kontrolu uslova pri operaciji čišćenja funkcije ili da se igramo sa dodavanjem dodatnih labela i goto skokova.
3) Izgubili smo priliku da budemo u mogućnosti da definišemo astraktan kod koji će kasnije da nam omogući da mnogo lakše prilagođavamo funkciju i biramo koja će rutina da rešava naš problem (možemo tako da definišemo bezbroj rutina)

Šta smo dobili? Očigledno ništa :)

Za kraj da remiziram. Pravi sistem izuzetaka je u C-u nemoguće simulirati ali je ovaj princip sa vraćanjem povratnih vrednosti hipervizoru najpribližnije što postoji pravom sistemu jer simulira "custom exceptione" koji imaju sposobnost da uslovno vrše skokove na delove koda (u ovom slučaju funkciju) koja može na potpuno izolovan način da reši problem koji je nastao. Ono što je još važnije je da kod nije nužno pregledniji i čistiji ukoliko sve može da se opazi odmah krajičkom oka. Ponekad se pravi problemi tek vide kada se počne sa prilagođavanjem koda za sopstvene potrebe i tada se gotovo uvek ispravnim pokaže pravila da zarad proširivosti i prave čitljivosti koda treba preskočiti "teoretske preporuke" i poslušati praksu :) A praksa kaže da goto treba izbegavati kao đavo krst i da ako se i dogodi da se negde u kodu primeni da od tog koda kasnij ene treba mnogo očekivati pri proširenju već da se više isplati sve napisati iz početka pa čak i po ceni gubljenja vremena jer se na kraju ono uvek više isplati od koda koje koristi goto :)

Ja ovde stajem jesr sam postao i samom sebi dosadan a ako nastavim rizikujem da me poslodavci likvidiraju do ujutru :D
Naslov: Re: goto
Poruka od: holodoc 12.11.2010, 23:39
Citat: marjan  11.11.2010, 23:30
-----

Hej, kako to da sam odmah po slanju poruke imao Utisak +1?? Mnogo pametan SMF, a? :))

Doduše, rasipa memoriju - pre neku poruku sam dobio "kilobajt" uz profil - pre sam bio bajt. LOL

goto sleep;
Izdresirali smo ga da svaki put kad neko postuje skraćenicu "K&R" ili sintagmu "Kuća pos'o, pos'o kuća" korisniku doda još jednu memorijsku pločicu :D Naravno pločicu možeš da dobiješ samo jednom u sto godina :)

Citat: gagi44  11.11.2010, 01:12Nije mi baš jasno šta je to klasičan softver a šta je to "ono ostalo". Pisao sam neke aplikacije koje su se izvršavale dva dana na izuzetno močnom serveru, probao sam i da pišem one koje se izvšavaju u deliću sekunde na sistemu sa par hiljada bajtova ram memorije a malo nešto baratam i sa ovim klasičnim softverom i ne mogu da kažem šta je lakše a šta teže.
Pa što koristiš termine koji ti nisu baš jasni  :P Šalim se naravno. Ja nisam nigde upotrebio sintagmu "klasičan softver" već "klasični razvoj sofver" koji za mene lično znači razvoj softvera u nekom od viših programskih jezika koji nemaju baš neke direktne veze sa programiranjem hardvera osim ako ne koriste neku vrstu API-ja za direktnu ili posrednu komunikaciju sa njim. Dakle sve što se generalno razvija u jezicima kao što su C++, C, C#, PHP, Java itd. itš.

Citat: gagi44  11.11.2010, 01:12Svaki ima svoju težinu, svaki nosi neke posebne izazove i svaki ima svoju posebnu draž.  Ja imam tezu da svako ko radi neku aplikaciju mora savršeno da poznaje alate koje koristi (programski jezici, tehnike programiranja, razvojna okruženja i slično) i  mora odlično da poznaje oblast kojoj je aplikacija namenjena (na primer ako radi obradu signala koja stiže od digitalnog stetoskopa mora da zna šta traži u tom signalu, što znači da mora da poznaje malo medicine)
Iako se u suštini generalno slažem sa ovim delom za alate i aplikacije ne mogu da se složim sa konstatacijom da neko ko je "klasičan programer" treba da poznaje oblast tipa medicine i slično. Ukoliko je u pitanju softversko inženjertsvo za izradu aplikacija specifične namene u kojem je potrebno napraviti istraživanja u pogledu nekih specifičnosti same aplikacije a koje su opet vezane za medicinu onda je u redu ali u svim ostalim slučajevima osnovni postulat kod rada u velikim softverskim kompanijama je da ti kao programer ne treba da znaš kompletne detalje o projektu :) Primera radi započeo si rad na web aplikaciji koja daljinski treba da osmatra i kontroliše pacijente za koje drugi tim izrađuje odgovarajuću mikroelektroniku ta ceo projekat. Kako ćete vi funkcionisati u tom slučaju? Tako što će projekt menadžer biti taj koji će svakome od vas dati odgovarajuća dnevna zaduženja i što ni tebe kao klasičnog programera a ni zaposlene u drugom timu neće opterećivati stvarima koje ne trebaju da znaju.

Tako elektroničar neće morati da vodi računa o tome da li ćeš ti u svom programu da koristiš bezsulovne skokove  :dzavo: ili ti o tome da li će elektroničar obezbediti dovoljnu temperaturnu stabilnost projektovane elektronike. Vi ćete biti organizovani tako da "elektroničar" svojim delom posla obezbedi tebi kao programeru odgovarajuće tehničke podatke i API putem kojeg ćeš ti moći da kontrolišeš datu elektroniku. Da stvar bude još interesantnija u toku razvoja tvog softverskog dela velika je verovatnoća da nećeš ni videti sam uređaj već da ćeš ispravnost svog koda i pridržavanje speicfikaciaj testirati sopstvenim aplikacijama kojima je to osnovni cilj. Dakle ne da ćeš pisati samu aplikaciju nego ćeš pisati i aplikacije za testiranje svoje aplikacije :)

To je budućnost (a kad malo bolje razmislim i sadašnjost) razvoja softvera. Potpuna apstrakcija elemenata u timu koji se bave istim projektom a imaju različita zaduženja.

Citat: gagi44  11.11.2010, 01:12Kod "mikroelektronike" moraš još da poznaješ i malo elektronike. Sve pojave u okruženju kod ovakvih sistema se odvijaju u realnom vremenu i ne smeš sebi dozvoliti da ih ispustiš u nekim situacijama a resursi su ti jako skromni. Kada nastane bug tokom testiranja na terenu teško je pronaći uzrok jer je teško reprodukovati tu situaciju sa terena u laboratoriji  a greška može da nastane kako zbog greške programera tako i zbog nekih uvrnutih razloga kao što je stalno uključivanje hidrofora u obližnjoj zgradi. Nema moćnih alata za ubijanje buba koje su ti na raspolaganja, ne možeš da zabodeš brejk. Dakle daleko više nepoznatih faktora je u igri što ti zagorčava život.
Upravo zbog toga se softver nakon objavljivanja stalno testira i ispravljaju njegove greške :) E sad ako klijent i dalje pored preporuke razvojnog tima dobija da dopusti dovoljno vremena za testiranje softvera tim tu zaista ne može mnogo da učini osim da na vreme instalira softver i moli se da su svi u timu bili raspoloženi kad su ga pisali :)

Citat: gagi44  11.11.2010, 01:12Verovatno su algoritmi koji su smešteni u jednu ploču ne veću od grafičke a koja obrađuje nekoliko telefonskih poziva daleko komplikovaniji od onih koje smo svi zajedno ikad pisali.
Današnji hardver je realno dostigao ograničenja koje postavlja fizika tako da se za razliku od rešenja koja su se razvijala ranije  danas za dobijanje boljih performansi koristi klasičan "brute force" pristup.  Nije algoritam za OpenGL transformacije toliko komplikovan (par trigonometrijskih funkcija ukombinovanih sa prvačkom matematikom) koliko su porasli zahtevi za dobijanjem boljih performansi u smislu broja obrađenih vertexa u jedinici vremena.

Citat: gagi44  11.11.2010, 01:12I podela na hardver i softver nije kruta i kao što neko reče "hardver je okamenjen softver". Ono što je softver današnjice može biti hardver sutrašnjice i obrnuto tako da je svako programiranje pomalo okrenuto ka hardveru.  :)
Nije baš tako :) Ja jesam radoznao po prirodi ali i dalje mislim da "klasičnog programera" ne treba uopšte da interesuje kako određeni kompajler funkcioniše ili kkao optimizuje kod. Jednostavno neke stvari su danas postale toliko opširne da bi letenje na sve strane samo značilo razvodnjavanje specifičnih sposobnosti a to u industriji nije baš najbolje jer kako kažu "majstor za sve nije sposoban nizašta" :)