Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: GCC:n keljumainen varoitus

vuokkosetae [10.11.2011 19:25:33]

#

Millähän tämän saisi tapettua sillai kauniisti, ilman GCC:n vipuihin kajoamista.
Tykkäisin pitää tuon -Wextran, mutta tahtoisin myös varoituksetonta koodia. Onko jotain tapaa sanoa kääntäjälle käyttäneeni tuota arvoa?

void foo(int * muutetaan, int monesti){
  int i;
  for(i=0;i<monesti;i++){
    *muutetaan++;
  }
  return;
}

gcc -c -Wall -Wextra test.c
test.c: Funktio öfooö:
test.c:4:5: varoitus: laskettua arvoa ei käytetä [-Wunused-value]

Selkeästihän tuo parametrin muutos on haluttu asia ja muita vaikutuksia ei haluta. Sitä sitten ihmetellään kutsujan puolella, mitä tapahtui.

Metabolix [10.11.2011 19:43:25]

#

Koodisi ei tee, mitä luulet sen tekevän. Nykyinen koodisi toimii näin:

int* vanha = muutetaan;
muutetaan++; /* Osoitin muuttuu, luku ei! */
*vanha;

Sen sijaan seuraavat vaihtoehdot toimivat oikein:

(*muutetaan)++;
++*muutetaan;

Selkeästihän olet siis itse mokannut ja kääntäjä varoittaa aivan syystä. Hieman koomista, että haluat viisaasti pitää kaikki varoitukset käytössä mutta et sitten osaa tulkita niitä. :P Hassua, ettet huomannut edes, että funktiosi tuottaa väärän tuloksen.

vuokkosetae [10.11.2011 20:08:18]

#

D'Oh!

Muissa paikoissa olikin ++*muutetaan. Ja keskeneräisissä testeissäni en ole vielä päässyt kiusaamaan tuota kyseistä muuttujaa. Mutta noiden plussien puoli oli kyllä niin naamioitu miina, etten sitä nähnyt. Joskus puusilmäys iskee.

jalski [10.11.2011 20:19:46]

#

Kannattaa pitää mielessä miten C välittää parametrit funktiolle (ovat siis kopioita, passed by value).

Mihin muuten tarvitset tuollaista aliohjelmaa? Tuon koko aliohjelman, jossa kasvatetaan osoitinta loopissa voisi nimittäin korvata yhdellä yhteenlaskulla.

vuokkosetae [10.11.2011 20:31:24]

#

Joo ja kun aina muistaisi noiden liittymisvoimakkuuden niin silloinhan se oisi niin hienoa.

Ja mielessäni olikin, että jotain siinä rivillä on mitä en hoksaa ja siksihän kysyinkin.

Kuten arvata saattaa tuo oli minimi, millä sain aikaiseksi tuon virheen. En harrasta foo() funktioita ja tiedoston nimetkin ovat toivottavasti pidemmät kuin test.c :) Oikeassa maailmassa loopissa mennään linkitettyä listaa läpi ja siitä mennään switchissä katsoen montako samantyyppistä ominaisuutta on. Eli ei se ihan yhteenlaskulla mene.

Torgo [15.11.2011 15:26:13]

#

vuokkosetae kirjoitti:

Selkeästihän tuo parametrin muutos on haluttu asia ja muita vaikutuksia ei haluta.

Kuten todettu, niin selkeästihän tuossa ei muuteta mitään parametria, joten varoitus on siltä osin aiheellinen.

Mutta tuohon ensimmäiseen kysymykseen, että onko jotain tapaa kertoa kääntäjälle sitä käyttämään tuota muuttujaa, vaikka sille ei näennnäisesti mitään tehdäkään, vastaus on että kyllä on. Anna muuttujalle volatile määre, joka kertoo kääntäjälle, että sitä ei saa optimoida. Kääntäjälle se on vakuutus siitä, että tiedät itse paremmin mitä muuttujan kanssa tehdään ja ei tehdä. Tämä versio pitäisi mennä kääntäjästä ilman varoituksia (vaikkakin toimii tapauksessasi eri tavalla kuin haluat):

void foo(volatile int * muutetaan, int monesti){
  int i;
  for(i=0;i<monesti;i++){
    *muutetaan++;
  }
  return;
}

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta