C-kielellä ohjelmoidessa jumituin tällaiseen ongelmaan, johon en nyt millään keksi ratkaisua. Main-funktiosta kutsutaan aliohjelmaa, jossa taas kutsutaan useita sisäkkäisiä aliohjelmia. Nyt jos jossain kohti tapahtuu virhe pitäisi palata takaisin ensimmäiseen aliohjelmaan. Miten tämän voisi toteuttaa?
Return-lauseella tietysti pääsee takaisin edelliseen aliohjelmaan, mutta jos ollaan jo hyvin "kaukana" ensimmäisestä aliohjelmasta (eli on tapahtunut jo useita peräkkäisiä aliohjelmakutsuja), tämä menee vähän hankalaksi. Tällöin joutuisi palaamaan return-lauseella aina yhden "pykälän" taaksepäin ja selvittämään if-lauseella aliohjelmakutsun jälkeen, tapahtuiko virhe (jolloin palataan taas return-lauseella) vai jatketaanko eteenpäin.
En nyt oikein osannut tätä fiksusti selittää, mutta toivottavasti joku ymmärsi.
C:ssä ei ole poikkeuksia, mutta setjmp ja longjmp voivat jossain määrin ajaa saman asian.
Itse olen tyytynyt käyttämään juuri selittämääsi if-lausetta ja erityisiä paluuarvoja virhetilanteissa (esim. -1). Tai jos ohjelma on todella hankala toteuttaa C:llä, käytän jotain toista kieltä.
Kannattaa tuossa pitää aika tarkkaan huoli, etteivät kyseiset funktiot jätä resursseja (muistia, tiedostoja yms.) vapauttamatta. Esimerkiksi seuraava funktio toimii aika kriittisesti väärin: vaikka tiedosto avataan alussa ja suljetaan lopussa aivan oikein, virhetilanteessa se jääkin auki!
void virhefunktio() { FILE *f = fopen("tiedosto.txt", "r"); // Koodia... if (virhe) { return; } // Koodia... fclose(f); }
Myös keskellä funktiota return-lauseen seurana pitäisi olla fclose.
Metabolix kirjoitti:
Kannattaa tuossa pitää aika tarkkaan huoli, etteivät kyseiset funktiot jätä resursseja (muistia, tiedostoja yms.) vapauttamatta. Esimerkiksi seuraava funktio toimii aika kriittisesti väärin: vaikka tiedosto avataan alussa ja suljetaan lopussa aivan oikein, virhetilanteessa se jääkin auki!
void virhefunktio() { FILE *f = fopen("tiedosto.txt", "r"); // Koodia... if (virhe) { return; } // Koodia... fclose(f); }Myös keskellä funktiota return-lauseen seurana pitäisi olla fclose.
Tämä on erinomainen esimerkki siitä missä on hyvä käyttää gotoa. Eli virhetilanteessa goto virhe; ja funktion lopussa sijaitsevan labelin virhe: jälkeen tulee kaikkien resurssien siivous.
Siis tarkemmin ajatellen erinomainen esimerkki siitä, minkä takia kannattaa suosia näppärämpiä kieliä kuin C. Veikkaisin että täälläkin ainakin 90% C-kieleen (tai C++:aan) liittyviä kysymyksiä esittävistä on tekemässä jotakin, joka onnistuisi paljon helpommin jollakin muulla kielellä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.