(puuttuva) muuttujamäärittely ?

C_Opiskelija

Onko nin, että C -kielessä on saalittua käyttää muuttujaa määrittelemättä sitä yhtään mitenkään siten, että käännös koodia.c -> koodia.obj onnistuu tästä huolimatta.

Toki, jos sitten kääntämisen lisäksi halutaa myös linkata koodia.obj -> koodia.exe

niin tällöin pitää ilmeisesti ottaa mukaan joko .c tai .obj -tiedosto, josta löytyy ko. puuttuvan muuttujan määrittely.

Onko siis näin, että jos teen näin:

void esimerkkialiohjelma {
muuttuja = 5;
}


niin se on sama asia, kuin jos ennen esimerkkialiohjelma:n määrittelyä olisi tällainen rivi:

external int muuttuja;

TAI ehkä

external static int muuttuja;

Eli siis että muuttujia voi käyttää niitä määrittelemättä, jolloin ne ovat oletuksena

"external (static?) int"

mutta linkkausvaiheesa viimeistään pitäisi jokaiselle käytetylle muuttujalle löytyä määrittelykin, käännösvaiheessa välttämättä ei tarvitse, näinkö ?

6

468

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • xyxyxy

      Kyllä se muuttuja jotenkin pitää määritellä. Esimerkiksi tällainen kääntyy .c -> .obj:

      extern int muuttuja;

      void esimerkkiohjelma() {
      muuttuja = 5;
      }

      mutta linkkausvaiheessa .obj -> .exe tulee virhe. Tämä johtu siitä, että extern kertoo, että muuttuja määritellään jossain muussa .obj -tiedostossa.

      Sen sijaan tämä kääntyy suoraan, koska tässä muuttuja määritellään lokaaliksi:

      void esimerkkiohjelma() {
      int muuttuja = 5;
      }

      samoin kuin tämä, koska oletuksena muuttuja on static (jos muistan oikein):

      int muuttuja;

      void esimerkkiohjelma() {
      muuttuja = 5;
      }

      tai tämä, koska muuttuja määritellään staattiseksi eli objektitietoston sisällä lokaaliksi:

      static int muuttuja;

      void esimerkkiohjelma() {
      muuttuja = 5;
      }

      • ogma

        Aikaisemmin K&R-tyyppisessä C-kääntäjässä oli mahdollista jättään pois funktion
        paluuarvon määrittely, jolloin funktion paluuarvoksi tuli automaattisesti int.
        Tämä on ollut jo pitkään (parikymmentä vuotta) huonojen ohjelmointikäytäntöjen
        listalla, koska sen kolmen lisämerkin (int) kirjoittamisen vaiva on huomattavasti
        pienempi kuin se riski, että koodia muokattaessa syntyy väärinymmärrys.

        Globaalin muuttujan määrittely staticiksi tai ilman tarkoittaa sitä, että static-
        määritelty muuttuja ei näy käännösyksikön ulkopuolelle. Eli jos jossain tiedostossa
        määritellään
        extern int muuttuja;
        ja toisessa tiedostossa
        static int muuttuja;
        niin linkattaessa objektitiedostoja yhteen, linkkeri valittaa puuttuvasta muuttujamäärittelystä.

        Tässäkin yhteydessä kaikki muuttujat käännösyksikön sisällä kannattaa määritellä staticeiksi
        ja muuttujien sisältöä penkomaan kannattaa luoda aksessoreita. Tämä ihan siksi, ettei
        kannata päästää kaikkia ratustelemaan privaatteja muuttujia ja vältytään varsinkin
        sulautetussa maailmassa hankaluuksilta (kuka muutti minun muuttujaani-syndrooma).

        Jos joku miettii suorituskykypenaltya, joka mahdollisesti funktiokutsusta, niin tälläiset
        aksessorit kuuluvat kaikista triviaaleimpiin optimointitehtäviin, jolloin
        int a = getMuuttuja();
        tyyppinen kutsu muunnetaan helposti
        int a = muuttuja;
        muotoon. Aksessorit mahdollistavat myös johdetut muuttujat, joiden arvo lasketaan muiden
        tietojen perusteella (esim. ikä voidaan laskea päiväyksen ja syntymäajan erotuksena jne.).
        No joo, vähän ohi topikin.....


      • C_Opiskelija

        En kysynyt, onko tuollainen muuttujan määrittelemättömyys mitenkään hyvää ohjelmointityyliä (mielestäni ei) vaan sitä, että se on kuitenkin ilmeisesti mahdollista !

        En siis ole koodaamassa ohjelmaa ja aikomassa jättää määrittelyjä pois, vaan ihmettelen olemassaolevaa (jonkun muun tekemää) koodia, jossa erästä muuttujaa ei ole moduli.c eikä vastaavassa moduli.h -tiedostossa määritelty mitenkään.

        Käännös menee silti kääntäjästä läpi ilman virheitä.

        Itse olet ymmärtänyt tilanteen näin:

        Jos ja kun moduli.c -tiedostossa viitataan muuttujaan, jotai ei ole määritelty "missään" niin C -kääntäjä olettaa että se on jossain toisessa .c -tiedostossa määritelty int -tyyppiseksi -> ei virheilmoitusta, mutta onnistunut käännös moduli.obj tiedostoksi.

        Kun nyt tehdään lopullinen käännös (=linkkaus) .exe -tiedostoksi, niin vasta tässä vaiheessa kääntäjä ottaa mukaan vaikkapa tiedoston "jokumuu.c" jossa ko. muuttuja on määritelty, ja siksi toimivan .exe -tiedoston linkkaus on tässä vaiheessa mahdollista.

        Kuitenkaan moduli.c EI sisällytä include -lauseella tiedostoa jokumuu.c eikä myöskään jokumuu.h

        Tästä ymmärtäisin, että vaikka se eihkä ei ole hyvän ohjelmointitavan mukaista, niin on kuitenkin mahdollista kääntää moduli.c -> moduli.obj vaikka ko. käännöksessä viitataan määrittelemättömään muuttujaan.

        Veikkaan, että jos vaikka siirrän "jokumuu.c" -tiedoston johonkin toiseen hakemistoon, josta C -kääntäjä ei sitä pysty etsimään, niin em. moduli.c -> moduli.obj -käännös onnistuis silti.

        Mutta linkkausvaiheessa, kun ei tyydytä .obj -tiedoston tuottamiseen vaan halutaan .exe, niin tässä vaiheessa käsittääkseni linkkausvaiheessa tulisi virheilmoitus jos ennen ko. työvaihetta esim. muuttaisin tiedostossa jokumuu.c olevan muuttujamäärittelyn pelkäksi kommentiksi.

        Muiden tekemistä C -ohjelmista tällaista koodia todellakin löytyy.

        Veikkanpa, että esim. tyypillisessä linux -distrossa mukana olevien C:llä tehtyjen ohjelmien lähdekoodeista vastaavia löytyis vaikka millä mitalla.

        Ehkä kyse on sitten ainakin C -kielen suunnittelijoiden kannalta modulaaarisuudesta äärimmilleen vietynä, kun pelkän .obj -tiedoston tuottamiseksi edes muuttujia ei ole ihan pakko määritellä, vaikka se toki suositeltavaa onkin.

        Onko muuten C -kääntäjissä tyypillisesti joku komentorivioptio joka joko a) muuttaa muuttujien määrittelyn jo käännösvaiheessa (ilman linkkausvaihetta) pakolliseksi tai b) ainakin varoittaa puuttuvista muuttujamäärittelyistä ?

        tosin voi olla, että eräiden ohjelmien osalta moisen varoitusvipusen käyttö käännöksessä tulostaisi useita sivuja pitkän varoituslistan ...


      • xyxyxy
        C_Opiskelija kirjoitti:

        En kysynyt, onko tuollainen muuttujan määrittelemättömyys mitenkään hyvää ohjelmointityyliä (mielestäni ei) vaan sitä, että se on kuitenkin ilmeisesti mahdollista !

        En siis ole koodaamassa ohjelmaa ja aikomassa jättää määrittelyjä pois, vaan ihmettelen olemassaolevaa (jonkun muun tekemää) koodia, jossa erästä muuttujaa ei ole moduli.c eikä vastaavassa moduli.h -tiedostossa määritelty mitenkään.

        Käännös menee silti kääntäjästä läpi ilman virheitä.

        Itse olet ymmärtänyt tilanteen näin:

        Jos ja kun moduli.c -tiedostossa viitataan muuttujaan, jotai ei ole määritelty "missään" niin C -kääntäjä olettaa että se on jossain toisessa .c -tiedostossa määritelty int -tyyppiseksi -> ei virheilmoitusta, mutta onnistunut käännös moduli.obj tiedostoksi.

        Kun nyt tehdään lopullinen käännös (=linkkaus) .exe -tiedostoksi, niin vasta tässä vaiheessa kääntäjä ottaa mukaan vaikkapa tiedoston "jokumuu.c" jossa ko. muuttuja on määritelty, ja siksi toimivan .exe -tiedoston linkkaus on tässä vaiheessa mahdollista.

        Kuitenkaan moduli.c EI sisällytä include -lauseella tiedostoa jokumuu.c eikä myöskään jokumuu.h

        Tästä ymmärtäisin, että vaikka se eihkä ei ole hyvän ohjelmointitavan mukaista, niin on kuitenkin mahdollista kääntää moduli.c -> moduli.obj vaikka ko. käännöksessä viitataan määrittelemättömään muuttujaan.

        Veikkaan, että jos vaikka siirrän "jokumuu.c" -tiedoston johonkin toiseen hakemistoon, josta C -kääntäjä ei sitä pysty etsimään, niin em. moduli.c -> moduli.obj -käännös onnistuis silti.

        Mutta linkkausvaiheessa, kun ei tyydytä .obj -tiedoston tuottamiseen vaan halutaan .exe, niin tässä vaiheessa käsittääkseni linkkausvaiheessa tulisi virheilmoitus jos ennen ko. työvaihetta esim. muuttaisin tiedostossa jokumuu.c olevan muuttujamäärittelyn pelkäksi kommentiksi.

        Muiden tekemistä C -ohjelmista tällaista koodia todellakin löytyy.

        Veikkanpa, että esim. tyypillisessä linux -distrossa mukana olevien C:llä tehtyjen ohjelmien lähdekoodeista vastaavia löytyis vaikka millä mitalla.

        Ehkä kyse on sitten ainakin C -kielen suunnittelijoiden kannalta modulaaarisuudesta äärimmilleen vietynä, kun pelkän .obj -tiedoston tuottamiseksi edes muuttujia ei ole ihan pakko määritellä, vaikka se toki suositeltavaa onkin.

        Onko muuten C -kääntäjissä tyypillisesti joku komentorivioptio joka joko a) muuttaa muuttujien määrittelyn jo käännösvaiheessa (ilman linkkausvaihetta) pakolliseksi tai b) ainakin varoittaa puuttuvista muuttujamäärittelyistä ?

        tosin voi olla, että eräiden ohjelmien osalta moisen varoitusvipusen käyttö käännöksessä tulostaisi useita sivuja pitkän varoituslistan ...

        Mikä kääntäjä on kyseessä? Nimittäin esimerkiksi linuxin peruskääntäjä gcc ei kyllä päästä läpi koodia, jossa kaikkia muuttujia ei ole määritelty. Oletko ihan varma ettei muuttuja ole määritelty jossain tiedostossa kuitenkin? Ettei vaan se ole joku c-kirjastojen oma muuttuja? gcc:n -Wall optiolla saa laitettua kaikki varoitukset päälle, jos niitä kaipaat. Tosin kyllä kyse ei liene tästä kääntäjästä, koska puhut ".exe":istä ja ".obj"-tiedostoista, jotka ovat windowsin omia juttuja.


      • C_opiskelija
        xyxyxy kirjoitti:

        Mikä kääntäjä on kyseessä? Nimittäin esimerkiksi linuxin peruskääntäjä gcc ei kyllä päästä läpi koodia, jossa kaikkia muuttujia ei ole määritelty. Oletko ihan varma ettei muuttuja ole määritelty jossain tiedostossa kuitenkin? Ettei vaan se ole joku c-kirjastojen oma muuttuja? gcc:n -Wall optiolla saa laitettua kaikki varoitukset päälle, jos niitä kaipaat. Tosin kyllä kyse ei liene tästä kääntäjästä, koska puhut ".exe":istä ja ".obj"-tiedostoista, jotka ovat windowsin omia juttuja.

        kyse ainakin näistä kahdesta C -kääntäjästä:

        tcc

        mingw-gcc (eli gcc:n windowsille portattu versio)

        Ainakin gcc:n mingw -versio päästää tuon läpi, siis käännettäessä .c -> .obj.

        Toki sitten linkkausvaiheessa huomataan, että se löytyy toisesta projektiin kuuluvasta .c -tiedostosta, jota kuitenkaan EI includoida tuota muuttujaa vain käyttävään .c -tiedostoon.

        En edes tiedä, sopiiko .c -tiedostoja yleensäkään includoida, vai onko niin, että #include on tarkoitettu lähinnä vain .h -tiedostoille.

        Tällainen tulee siis vastaan itse tcc:n lähdekoodeissa.

        tcc:n voi siis toki kääntää itsellään, mutta kun ne lähdekoodit on ensin saatava exe:ksi, niin 1. käännöskerta siis väkisinkin gcc:n mingw -versiolla.

        tcc siis löytyy täältä:

        http://bellard.org/tcc/

        täytynee tuon "puuttuvan" muuttujan nimikin joskus selvittää, nyt ei jaksa ... (jos asia vielä jäi epäselväksi)


      • Nero CpLuSpLus;
        C_opiskelija kirjoitti:

        kyse ainakin näistä kahdesta C -kääntäjästä:

        tcc

        mingw-gcc (eli gcc:n windowsille portattu versio)

        Ainakin gcc:n mingw -versio päästää tuon läpi, siis käännettäessä .c -> .obj.

        Toki sitten linkkausvaiheessa huomataan, että se löytyy toisesta projektiin kuuluvasta .c -tiedostosta, jota kuitenkaan EI includoida tuota muuttujaa vain käyttävään .c -tiedostoon.

        En edes tiedä, sopiiko .c -tiedostoja yleensäkään includoida, vai onko niin, että #include on tarkoitettu lähinnä vain .h -tiedostoille.

        Tällainen tulee siis vastaan itse tcc:n lähdekoodeissa.

        tcc:n voi siis toki kääntää itsellään, mutta kun ne lähdekoodit on ensin saatava exe:ksi, niin 1. käännöskerta siis väkisinkin gcc:n mingw -versiolla.

        tcc siis löytyy täältä:

        http://bellard.org/tcc/

        täytynee tuon "puuttuvan" muuttujan nimikin joskus selvittää, nyt ei jaksa ... (jos asia vielä jäi epäselväksi)

        Kaikenkaikkiaan hakoteillä tässä säikeessä ollaan: muuttujan määrittely ja muuttujan esittely ovat kaksi eri asiaa. Muuttuja on esiteltävä, ennen kuin muuttujaa määritelläkään.


    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Minkähän takia ns. persuille ei tunnu työ maistuvan?

      Vaikuttavat olevan joutoväkeä syystä tai toisesta  – työttömiä tai työeläkeloisia. Muiden rahoilla pötköttelevää väkeä,
      Maailman menoa
      73
      4271
    2. Miksiköhän vasemmistossa on niin paljon ns. tapatyöttömiä ja muita köyhiä?

      Tokihan Minja Koskela oli sitä mieltä, että ei terveenkään ihmisen ole pakko tehdä töitä, sitä neuvoa moni vassu noudatt
      Maailman menoa
      17
      2728
    3. Olit ihan

      Kiihkona silloin. Sen näki ja lähes tunsi. Ei tainnut olla kaukana et olisit vetänyt lähellesi jos siihen olisi hetki tu
      Ikävä
      24
      2477
    4. Kyllä on Vasemmistoliitosta Koskelan johdolla tullut todellinen ääripuolue

      se on niin tulipunainen kuin olla voi, ja selvästi haluaa jatkuvasti eripuraa, ja repiä kansaa kahtia. Siinä on jo vuod
      Maailman menoa
      15
      2422
    5. Trump huonommassa kunnossa kuin Usasta virallisesti sanotaan?

      "Terveys on vakaa mutta ei normaali".Uskallan melkein sanoa,että Trumpin terveydentilaa kaunistellaan.Myös se että se nu
      Maailman menoa
      108
      2280
    6. Suomen veroaste 5 %-yks liian matala

      Palauttamalla kokonaisveroaste 1990-luvun tasolle saadaan hyvinvointivaltion palvelut rahoitettua ilman velan ottoa.
      Maailman menoa
      110
      2194
    7. Kolme neljästä suomalaisesta kannattaa miljonääriveroa

      Kertoo vasemmistoliiton teettämä kysely. Veron ulkopuolelle jätettäisiin asunto. "Puolet vastaajista oli sitä mieltä, e
      Maailman menoa
      99
      2141
    8. Evoluutioon ja alkuräjähdykseen uskominen vaatii todella vahvaa uskoa

      Että tyhjästä syntyi ja kehittyi kaikki se mitä näemme ympärillämme.
      Luterilaisuus
      609
      1946
    9. MTV: Harvinainen haastattelu! Vappu Pimiä kommentoi vihdoinkin uutta TTK-juontajaa

      TTK-juontajaspekuloinnit käyvät edelleen kuumana. Kenet sinä haluaisit uudeksi TTK-juontajaksi? Kommentoi alle! Lue,
      Suomalaiset julkkikset
      14
      1925
    10. Yleveron tuotto siirrettävä S-ryhmälle

      Yleisradio on mukana kansanmurhassa. Tuollaista ei voi tukea verovaroin. S-ryhmä on ainoa selkärankainen iso toimija S
      Maailman menoa
      23
      1683
    Aihe