4.2. ALIOHJELMAT 71. Tulosvälitteisyys (call by result) Tulosvälitteinen parametri kopioidaan lopuksi

Samankaltaiset tiedostot
Aliohjelmat. 1 Kutsusekvenssit. Antti-Juhani Kaijanaho 5. helmikuuta 2007

11/20: Konepelti auki

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 13. lokakuuta 2009

Luento 4 (verkkoluento 4) Aliohjelmien toteutus

TIES542 kevät 2009 Kontrollivuon ohjaus

Luento 4 Aliohjelmien toteutus

Luento 4 (verkkoluento 4) Aliohjelmien toteutus

Jakso 4 Aliohjelmien toteutus

Aliohjelmatyypit (2) Jakso 4 Aliohjelmien toteutus

Jakso 4 Aliohjelmien toteutus

Aliohjelmatyypit (2) Jakso 4 Aliohjelmien toteutus

Jakso 4 Aliohjelmien toteutus

Jakso 4 Aliohjelmien toteutus. Tyypit Parametrit Aktivointitietue (AT) AT-pino Rekursio

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Luento 4 Aliohjelmien toteutus

Luku 7. Aliohjelmat. 7.1 Kutsusekvenssit. Aliohjelma (subroutine) on useimpien kielten tärkein kontrollivuon ohjausja abstrahointikeino.

Luento 4 Aliohjelmien toteutus

Osoitin ja viittaus C++:ssa

Luento 4 Aliohjelmien toteutus. Tyypit Parametrit Aktivointitietue (AT) AT-pino Rekursio

samalla seuraavaan puoliavaruuteen (sukupolveen), jota siivotaan harvemmin.

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 27. lokakuuta 2009

C++11 lambdat: [](){} Matti Rintala

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma muuttaa parametrejaan tai globaaleja muuttujia, tulostaa jotakin jne.

ITKP102 Ohjelmointi 1 (6 op)

Taulukot. Jukka Harju, Jukka Juslin

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Jatkeet. TIES341 Funktio ohjelmointi 2 Kevät 2006

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

1. Omat operaatiot 1.1

Groovy. Niko Jäntti Jesper Haapalinna Group 31

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

4. Luokan testaus ja käyttö olion kautta 4.1

Harjoitustyö: virtuaalikone

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmoinnin peruskurssien laaja oppimäärä

Javan perusteita. Janne Käki

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmoinnin peruskurssien laaja oppimäärä

815338A Ohjelmointikielten periaatteet

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

7. Oliot ja viitteet 7.1

Algoritmit 1. Luento 3 Ti Timo Männikkö

Olio-ohjelmointi Javalla

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

Hohde Consulting 2004

ITKP102 Ohjelmointi 1 (6 op)

Ongelma(t): Miten mikro-ohjelmoitavaa tietokonetta voisi ohjelmoida kirjoittamatta binääristä (mikro)koodia? Voisiko samalla algoritmin esitystavalla

Monipuolinen esimerkki

A TIETORAKENTEET JA ALGORITMIT

Sisällys. 3. Muuttujat ja operaatiot. Muuttujat ja operaatiot. Muuttujat. Operaatiot. Imperatiivinen laskenta. Muuttujat. Esimerkkejä: Operaattorit.

3. Muuttujat ja operaatiot 3.1

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 26. lokakuuta 2009

ELM GROUP 04. Teemu Laakso Henrik Talarmo

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

815338A Ohjelmointikielten periaatteet

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

Vertailulauseet. Ehtolausekkeet. Vertailulauseet. Vertailulauseet. if-lauseke. if-lauseke. Javan perusteet 2004

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

TAMPEREEN TEKNILLINEN YLIOPISTO

Tietotekniikan valintakoe

Ohjelmointi 1 C#, kevät 2013, 2. tentti

tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi

Pong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana

TAMPEREEN TEKNILLINEN YLIOPISTO

Osoittimet ja taulukot

Sisältö. 22. Taulukot. Yleistä. Yleistä

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

Kehittää ohjelmointitehtävien ratkaisemisessa tarvittavia metakognitioita!

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Rakenteiset tietotyypit Moniulotteiset taulukot

Ohjelmistojen mallintaminen, sekvenssikaaviot

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. IX Suunnittelumallit Proxy, Factory Method, Prototype ja Singleton

Luokat ja oliot. Ville Sundberg

Ohjelmointikieli TIE Principles of Programming Languages Syksy 2017 Ryhmä 19

Dynaaminen muisti. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät 2017.

12. Monimuotoisuus 12.1

5/20: Algoritmirakenteita III

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

7. Näytölle tulostaminen 7.1

Tutoriaaliläsnäoloista

Laiska laskenta, korekursio ja äärettömyys. TIEA341 Funktio ohjelmointi Syksy 2005

TIE PRINCIPLES OF PROGRAMMING LANGUAGES Eiffel-ohjelmointikieli

Apuja ohjelmointiin» Yleisiä virheitä

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 16.3

Rajapinta (interface)

kontrollivuon analyysejä optimointiensa tueksi ja myös tiettyjen merkitysopillisten

Tieto- ja tallennusrakenteet

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Tietorakenteet ja algoritmit

12. Monimuotoisuus 12.1

Tietueet. Tietueiden määrittely

Transkriptio:

4.2. ALIOHJELMAT 71 sisältyä kaikki tarvittavat kontrollia ohjaavat rakenteet. Jos se on lause (yleensä lohko), niin on ratkaistava, miten paluuarvo ilmaistaan. Joissakin kielissä (esimerkiksi Pascal) funktion nimeen sijoittaminen ilmaisee paluuarvon. Toisissa kielissä (kuten C-sukuiset) on erityinen return-lause, jolla funktiosta poistutaan paluuarvo ilmaisten. 4.2.2 Parametrinvälitysmekanismit Olemme puhuneet edellä aliohjelman argumenteista. Kuten edellä sanottiin, ne ovat ne datat, jotka aliohjelmalle annetaan ne ovat lausekkeita, jotka ovat osa aliohjelmakutsua. Asian toinen puoli on se, että aliohjelman sisällä nämä näkyvät paikallisina muuttujina. Näitä muuttujia sanotaan aliohjelman parametreiksi (parameter). Toisin sanoen siinä missä kutsuja näkee argumentteja, kutsuttava näkee parametreja. Toisinaan argumentista käytetään nimeä todellinen parametri (actual parameter), jolloin parametria sanotaan muodolliseksi parametriksi (formal parameter). Sitä mekanismia, jolla argumentti ja parametri kytketään toisiinsa, sanotaan parametrinvälitysmekanismiksi (parameter passing mechanism). Seuraavat neljä mekanismia ovat tavallisimmat: Arvovälitteisyys (call by value) Arvovälitteinen parametri on kopio argumentista: parametrin arvo on aliohjelman alussa argumentin arvo, ja parametriin tehdyt muutokset eivät näy argumentissa. Tulosvälitteisyys (call by result) Tulosvälitteinen parametri kopioidaan lopuksi argumentiksi: parametrin arvo on aliohjelman alussa määräämätön, mutta siihen tehdyt muutokset välitetään argumenttiin kopioimalla parametri argumenttiin aliohjelman palatessa. Arvo-tulosvälitteisyys (call by value-result) Arvo-tulosvälitteinen parametri on kopio argumentista, ja se kopioidaan lopuksi argumentiksi: parametrin arvo on aliohjelman alussa argumentin arvo, ja parametriin tehdyt muutokset välitetään argumenttiin kopioimalla parametri argumenttiin aliohjelman palatessa. Viitevälitteisyys (call by reference) Argumentti ja parametri ovat sama olio, joten kaikki parametriin tehdyt muutokset näkyvät välittömästi argumentissa. Nykyaikana näistä tavallisimmat ovat arvovälitteisyys ja viitevälitteisyys. Harvinaisempi ja nykyisin huonoksi todettu mekanismi on nimivälitteisyys (call by name). Idea on se, että argumenttilauseketta ei lasketa kutsuhetkellä, vaan ohjeet sen laskemiseksi annetaan aliohjelmalle. Kun aliohjelma käyttää parametria, se laskee argumenttilausekkeen arvon. Tämä tehdään uudestaan

72 LUKU 4. KONTROLLI joka kerta, kun parametria käytetään. Sivuvaikutusten kanssa tällainen voi aiheuttaa kaikenlaista vinkeää (etsipä jostain käsiisi tietoa vekottimesta nimeltä Jensen s device) ja myös ikävää (koetapa kirjoittaa toimiva swap-aliohjelma). Toimivampi mutta varsin harvinainen versio nimivälitteisyydestä on nimeltään tarvevälitteisyys (call by need). Idea on sama kuin nimivälitteisyydessä, mutta tarvevälitteisyydessä huolehditaan siitä, että jokainen tarvevälitteinen parametri lasketaan samalla aktivaatiokerralla korkeintaan kerran seuraavilla käyttökerroilla käytetään aiemman laskennan tulosta. Tarvevälitteisyyttä kutsutaan toisinaan laiskaksi laskennaksi (lazy evaluation), ja sitä käytetään väljien funktioiden toteuttamisessa. 4.2.3 Aktivaatiotietue Pinoon aliohjelmakutsun yhteydessä rakentuva tietue (joka siis sisältää aliohjelman parametrit paluuosoite mukaanlukien) on nimeltään aktivaatiotietue (activation record) tai kehys (frame). Jokainen kerta, kun aliohjelmaa kutsutaan, syntyy aliohjelman uusi aktivaatio (activation), ja sen aktivaatiotietue sisältää kaiken sen tiedon, mitä tuosta nimenomaisesta aktivaatiotiedosta on pidettävä yllä ja erillään muista aktivaatioista. Aliohjelma itse lisää siihen tilan paikallisille, pinodynaamisille muuttujilleen. Joissakin tilanteissa aktivaatiotietue on staattinen olio; tällöin kyseinen aliohjelma ei voi olla rekursiivinen eikä vapaakäyntinen (reentrant). Joissakin kielten toteutuksissa aktivaatiotietue on kekodynaaminen olio joskus tämä on jopa välttämätöntä. Aktivaatiotietueen paikka ei ole tavallisesti tiedossa ennen suorituksen alkua (se on tiedossa vain, jos aktivaatiotietue on staattinen olio). Sen sijaan sen osien sijainti suhteessa tietueen alkuun on hyvinkin tiedossa ennen suorituksen alkua. Senpä takia pääsy aktivaatiotietueessa oleviin tietoihin järjestetään käyttäen lähes jokaisesta prosessorista löytyvällä rekisteri-ja-siirtymä-osoituksella. Kielen toteutus varaa yhden rekisterin osoittamaan sen aliohjelman aktivaatiotietuetta, jolla kontrolli on. Tätä rekisteriä sanotaan kehysosoitinrekisteriksi (frame (pointer) register) tai kantaosoitinrekisteriksi (base pointer register). Kun jotain toista aliohjelmaa kutsutaan, tulee tuon rekisterin sisältö tallentaa jonnekin. Käytännössä se tallennetaan aliohjelman alkaessa kutsutun aliohjelman omaan aktivaatiotietueeseen, ja se palauttaa rekisterin arvon ennen paluutaan. Tätä tallennettua kehysosoitinrekisterin arvoa sanotaan dynaamiseksi linkiksi (dynamic link) sitä voitaisiin käyttää myös esimerkiksi dynaamisen vaikutusalueen toteuttamiseen. Kaikki ne aktivaatiotietueet, joihin pääsee dynaamisten linkkien kautta siitä tietueesta, jonka osoite on kehysosoitinrekisterissä, muodostavat kutsupinon (call stack) eli aktivaatiopinon (activation stack) eli dynaamisen ketjun (dynamic chain).

4.2. ALIOHJELMAT 73 Joissakin kielissä aliohjelmia voidaan kirjoittaa toisten aliohjelmien sisään. Mikäli tällaisessa kielessä on käytössä staattinen vaikutusalue, tulee jotenkin aliohjelmasta olla pääsy sitä staattisesti ympäröivien aliohjelmien sopivan aktivaation paikallisiin muuttujiin (eli aktivaatiotietueisiin). Yksinkertaisessa tapauksessa tällaista aliohjelmaa voidaan kutsua vain itsestään, siitä aliohjelmasta, jossa se on määritelty, sekä niistä aliohjelmista, jotka on määritelty sen itsensä sisällä (staattisessa mielessä). Tällaisessa tilanteessa luonteva valinta staattisesti ympäröivän aliohjelman aktivaatioksi, johon pitää päästä käsiksi, on se, jossa kutsu tapahtuu. Kun kutsu tapahtuu, annetaan aliohjelmalle piilotettuna argumenttina osoitin tähän aktivaatiotietueeseen. Tällöin tuo osoite jää osaksi kutsutun aliohjelman aktivaatiotietuetta; tuota osoitetta sanotaan staattiseksi linkiksi (static link). Aktivaatiotietueet, joihin pääsee staattisten linkkien kautta siitä tietueesta, jonka osoite on kehysosoitinrekisterissä, muodostavat staattisen ketjun (static chain). Staattisen vaikutusalueen ollessa voimassa mihin tahansa näkyvään paikalliseen muuttujaan pääsee käsiksi hakemalla sitä staattisen ketjun kautta. Kussakin tilanteessa tiedetään ennen suorituksen alkua, kuinka syvällä staattisessa ketjussa kukin muuttuja on, ja tämän perusteella voidaan muuttujanhakukoodi generoida suoraviivaisesti: ladataan johonkin rekisteriin ensin kehysosoitinrekisterin arvo, sitten ladataan tuon osoittimen kautta staattinen linkki tuohon rekisteriin ja iteroidaan tätä tarpeeksi monta kertaa. Lopuksi tuota rekisteriä voidaan käyttää kuin kehysosoitinrekisteriä ikään hakemaan löydetyn aktivaatiotietueen sisältämä muuttuja. Erityisesti 1970- ja 1980-luvun kääntäjät yrittivät optimoida tätä näyteikkunatekniikalla (display technique). Tässä pidetään yllä erityistä taulukkoa, johon on koottu kaikki staattiseen ketjuun kuuluvat staattiset linkit. Tällöin muuttujan haku vaatii tämän näyteikkunataulukon (display) indeksoinnin ja sitten tuloksena saadun osoitteen käyttämisen kuten edellä muuttujan hakemiseen. Iterointi jää kokonaan pois. Käytännössä tästä ei kuitenkaan ole ollut hyötyä, koska näyteikkunan ylläpito vaatii yleensä enemmän työtä kuin mitä muuttujanhaussa säästyy: yleensä muuttujanhakuja muualta kuin omasta aktivaatiotietueesta on harvoin, ja silloinkin kun niitä on usein, ne voidaan optimoida tehokkaammin yleisemmillä tekniikoilla, esimerkiksi yhteisen alilausekkeen optimoinnilla. Silti näyteikkunatekniikka voi olla harkinnan arvoinen prosessoreilla, joissa on vähän rekistereitä. Mikäli aliohjelma voidaan antaa argumenttina toiselle aliohjelmalle, monimutkaistuu staattisen linkin hakeminen. Tällöin käytännössä argumenttina antajan (joka on siinä asemassa, kuin edellä oli aliohjelman kutsuja) tulee antaa argumenttina (piilossa) myös staattinen linkki, jotta sen saaja voisi kutsua alioh-

74 LUKU 4. KONTROLLI jelmaa antaen sille tuo staattinen linkki (omaansa se ei yleisessä tapauksessa voi antaa). Joissakin kielissä aliohjelmat ovat täysivaltaisia (first class), eli niitä voidaan tallentaa muuttujiin, viedä parametrina ja palauttaa paluuarvona vapaasti. Tällöin aliohjelmalla tulee olla olio, joka sitä edustaa muuttujissa, aliohjelman paluuarvona ja argumenttina. Mikäli kielessä aliohjelmat eivät voi olla sisäkkäisiä, pelkkä aliohjelman koodin alun osoite riittää olion sisällöksi. Näin toimitaan esimerkiksi C:ssä (funktio-osoitin). Muussa tapauksessa oliossa pitää tuon osoittimen lisäksi olla myös staattinen linkki, joka annetaan kutsuttaessa aliohjelmalle piiloargumenttina. Tällaista oliota sanotaan toisinaan sulkeumaksi (closure). 4.2.4 Vuorottaisrutiinit Sukua aliohjelmakäsitteelle on sellainen käsite kuin vuorottaisrutiini (coroutine). Vuorottaisrutiinia kutsutaan kuten aliohjelmaa, ja siinä syntyy vastaavalla tavalla aktivaatiotietue. Ero on siinä, että vuorottaisrutiini voi palauttaa kontrollin väliaikaisesti kutsujalleen; tällöin kutsuja voi toimia, kunnes se antaa kontrollin takaisin vuorottaisrutiinille, jolloin sen suoritus jatkuu siitä mihin se jäi. Tällainen pallottelu voi jatkua pitkäänkin, kunnes vuorottaisrutiini palaa aliohjelman tavoin lopullisesti. 4.2.5 Metodit OO-olion etuoikeutetut aliohjelmat, metodit (methods), eroavat tavallisista aliohjelmista kahdella tavalla: aliohjelman nimi sidotaan aliohjelman koodiin vasta ajon aikana, riippuen kohdeolion tyypistä eikä niinkään sitä edustavan muuttujan tyypistä, ja aliohjelmalle annetaan kohdeolio piilotettuna parametrina. Metodin sidonta (method binding) kirjoitetaan tavallisesti syntaksilla, jossa kohdeoliota edustava lauseke on pisteoperaattorin (tai joskus jonkin muun operaattorin) vasen operandi ja metodin nimi on oikea operandi. Syntaksista riippumatta sen merkitys on kuitenkin sama. Tämän sidontalausekkeen tuloksena on aliohjelma-arvo, joka sisältää olion itseviitteen ja viitteen metodin koodiin. Kun tätä kutsutaan, itseviite tulee piiloparametriksi. Metodin sidonta tapahtuu tavallisesti siten, että OO-olioon liittyy viittaus luokkaolioon, jossa on metoditaulu (method table, vtable), joka sisältää koodien osoitteita. Kuhunkin metodiin liittyy indeksi taulukkoon. Kun metodin sidonta tapahtuu, indeksoidaan kohdeolion luokkaolion metoditaulua metodin indeksillä, ja metodin koodiksi valitaan se, jonka osoite näin löytyy.

4.2. ALIOHJELMAT 75 On hyvä huomata, että sidontaoperaation tulos muistuttaa huomattavasti sulkeumaa. Samalla tulee huomatuksi, että itseviite muistuttaa kovasti staattista linkkiä. Jos tätä analogiaa halutaan viedä vielä pidemmälle, päädytään ajatukseen, jossa OO-olio itse on jonkin aliohjelman aktivaatiotietue tämä aliohjelma lienee sitten olion luokka, mutta se ei oikeastaan ole aliohjelma vuorottaisrutiini: kun olio luodaan, luokka eli vuorottaisrutiini käynnistyy (paikalliset muuttujat saavat arvonsa; tämä vastaa rakenninta), minkä jälkeen vuorottaisrutiini palauttaa kontrollin olion luontia pyytäneelle; kun vuorottaisrutiinille palautetaan kontrolli, se tekee mahdolliset purkamistoimenpiteet. Toisaalta analogia voidaan kääntää ylösalaisin: aliohjelma voidaan ajatella OOolioksi: aktivaatiotietue on OO-olio, ja aliohjelman sisällä määritellyn aliohjelman kutsu vastaa metodikutsua. Tehtävä 8 Onko aliohjelma OO-olio vai OO-olio aliohjelma? Vai ovatko ne jonkin kolmannen käsitteen ilmentymiä?