Category: Uncategorized

  • Banging my head against C pointer dereference

    The pointers always get me when I try my hands at C. Now, I’m not dumber than most people, and the basic idea is pretty clear to me. But what trips my brain each time is the notation of declaration.

    It’s not always illogical. After all, as K&C points out, int *ip is intended as a mnemonic; it says that the expression *ip is an int. Okay, that seems innocent enough, but in fact it’s a two-edged sword. What about when you’re declaring a pointer as a parameter for a function, then calling the function? Compare these two short programs below:

    Listing 1. Listing 2.
    int foo(int i);
    int main() {
     int j = 1;
     foo(j);
     return 0;
    }
    
    int foo(int i) {
      /* do something with i */
      return 0;
    }
    int foo(int *ip);
    int main() {
      int j = 2;
      foo(&j);
      return 0;
    }
    
    int foo(int *ip) {
      /* do something with (*)ip */
      return 0;
    }

    For the first program, it’s easy to see that the parameter of foo(), i, is assigned the contents of j from main(): you’re in effect saying:

    1. Let foo() have one parameter, i, of type int.
    2. From main(), assign the value of j, also of type int, to i.

    But for the second one, foo() has to be called with an address (a pointer), and yet the declaration, with the mnemonic notation in place, seems to call for an int:

    1. Let foo() have one parameter, *ip, of type int.
    2. From main(), assign the value of &j, of type… uhh… pointer, to… uhh… ???

    This difficulty for me to grasp what type of a parameter foo() should be called with is due to the mnemonic notation in int *ip: when you have an int <something> as a parameter declaration, you expect to assign the parameter something that is of type int — not something that is a pointer to an int.

    Now, if I give up the mnemonic and instead write the declaration as int* ip, the code translates to natural language quite fluidly:

    Listing 3.
    int foo(int* ip);
    int main() {
      int j = 2;
      foo(&j);
      return 0;
    }
    
    int foo(int* ip) {
      /* do something with (*)ip */
      return 0;
    }
    1. Let foo() have one parameter, ip, which is a pointer to an int.
    2. From main(), assign the value of &j, also a pointer to an int, to ip.

    Of course, this notation opens a whole new can of worms. Consider the following declaration:

    int* i, j;

    Is j a pointer now, or just an int? It’s way too open to misinterpretation to make this notation commendable despite the previous advantage in readability.

    So I’m better off sticking to the mnemonic notation, and just trying to get my head around it. For that, I’m still in desperate need for an easy translation of such code into natural language.

    Maybe the mnemonic is the root of the problem. It’s a really bad mnemonic because it almost always works, but then there’s (at least) this one case, where you’re better off not remembering it, because it screws up your logic if you do. So I should think of int *ip as ip is a pointer to an int and just forget about the fact that it resembles a declaration of an int called *ip.

  • It’ses to itses

    For some time now, I’ve been using a Greasemonkey script to fix the most prevalent spelling mistakes on the Interwebs. Incorrect apostrophes are particularly painful, particularly prevalent and also particularly cumbersome to fix — the latter two being due to the complexity of the rules governing the use of apostrophes, obviously.

    To tackle this, I’ve now adopted brute tactics: I simply replace each instance of it’s with an its. So far I must say it has felt less painful to encounter an its which should have been an it’s than it is the other way round.

  • Kolumni: Haasteita etsimässä

    Tämän blogin päivitystahti on viime aikoina hiipunut, mutta se ei suinkaan merkitse sitä, etteikö ongelmanratkaisu minua enää kiinnostaisi. Kaikki ensiasennuksen jälkeen kohtaamani pulmat, jotka yleensäkään ovat ratkaistavissa, alkavat vain olla ratkaistut — nykyisin jotakuinkin kaikki vain yksinkertaisesti toimii niin kuin pitää tai niin kuin haluan. Päivitysten myötä järjestelmä ei tietenkään pysy täysin muuttumattomana, mutta pelkät turvallisuuspäivitykset eivät kuitenkaan yleensä juurikaan horjuta hyvin toimivaa järjestelmää.

    Koska ongelmanratkaisu siis edelleenkin kiinnostaa minua, en aiokaan pysyä Hardy Heronissa loputtomiin, vaan aion päivittää järjestelmäni myöhemmin tänä vuonna julkaistavaan versioon 8.04.1 ja edelleen Intrepid Ibexiin loppuvuodesta. Kuten Hardynkin tapauksessa, otan luultavasti lievän ennakkolähdön, ihan vain jännityksen vuoksi.

    Sillä välin saan jännitystä ja haasteita tarpeekseni, kiitos VirtualBoxin. En enää muista mitä kautta tutustuin Innotekin kehittelemään ja nykyisin Sun Microsystemsin omistamaan virtualisointiratkaisuun, mutta veljet kuinka tyytyväinen olenkaan, että tutustuin! Alunalkujaan asensin VirtualBoxin, koska halusin kokeilla olisiko mahdollista ajaa Microsoftin Messengeriä siinä. Ei pidä käsittää väärin; pääasiallinen pikaviestimeni on ollut Pidgin jo pitkän aikaa — se oli sitä jo silloin, kun vielä käytin Windowsia — mutta joudun silloin tällöin käyttämään Messengeriä videopuhelimena vaihtoehdottoman kontaktin takia.

    No, Messengerhän toimi mitä parhaiten, ja itse asiassa se oli lopullinen niitti ei-virtualisoidun Windowsin arkkuun tietokoneessani: poistin Windows-osion ja laajensin Ubuntun osiot kattamaan koko kiintolevyni. Nyt voin aina Messengeriä tarvitessani potkia virtuaalikoneen käyntiin yhdessä ikkunassa työpöydälläni, mikä on paljon yksinkertaisempaa kuin kaksoiskäynnistäminen. Ehkä kaikkein parasta VirtualBoxissa on sen joviaali lisensointi: ohjelmasta on tarjolla avoimen lähdekoodin versio, ja lisäksi yksityis- ja arviointikäytössä ilmainen suljettu versio. Avoimen lähdekoodin versiosta puuttuu joitain vaativia ominaisuuksia, joiden joukossa on USB-tuki. Joudun siksi itse käyttämään suljettua versiota, koska webkamerani (jota tietysti tarvitsen videopuheluihin) on tyypillinen USB-liitäntäinen vekotin.

    Tätä nykyä pääasiallinen VirtualBoxin käyttöni ei kuitenkaan vaadi USB-tukea, ja tämä käyttö on sitä joka tarjoaa minulle haastetta: asentelen hullun lailla kaiken maailman käyttöjärjestelmiä VirtualBoxin virtuaalitietokoneisiini. Käyttöjärjestelmistä kiinnostuneelle VirtualBox onkin unelmien täyttymys. Virtualisointi mahdollistaa niiden asentelun tuotantojärjestelmää (jos peruskäyttäjän työpöytäkonetta sellaiseksi voi kutsua) vaarantamatta. Olen kokeillut Debian GNU/Linuxia (vakaata ja epävakaata jakeluversiota), Gentoota, Fedoraa, asentanut tietysti rinnakkaisen Ubuntun (monta kertaa), Slackwarea, LFS:ää, Debian GNU/Hurdia, FreeBSD:tä, OpenBSD:tä, ReactOSia, Syllablea… ja vielä on jäljellä paljon kaikenlaista, mitä aion kokeilla!

  • Second Life jumiuttaa työpöydän

    Lähtökohta
    Näytönohjaimeni on Connect 3D:n valmistama, AGP-väylässä kiinni oleva Radeon 9600 -piirisarjalla varustettu All In Wonder. Olen valinnut näytönohjaimelle avoimen lähdekoodin ajurin (ati) käyttöön. Olen määritellyt ikkunointiympäristön asetuksissa EXA-kiihdytysmenetelmän käyttöönotetuksi.
    Olen asentanut Second Life -pelin asentamalla secondlife-install -paketin getdeb-sivustolta. Minulla on Second Life -tili, ja olen käynnistänyt pelin ja kirjautunut onnistuneesti sisään.
    Ongelma
    Liikuttuani jonkin aikaa pelin virtuaalimaailmassa työpöytä lakkaa vastaamasta näppäinten painalluksiin, ja jumiutuu lukuunottamatta hiiren osoitinta, joka reagoi normaalisti hiiren liikkeisiin. Työpöydän alapaneeliin lisäämäni Järjestelmän tila -sovelma, joka näyttää suoritinkäyttöä, paljastaa, että hetkeä ennen jumiutumista suoritinkäyttö on kohonnut sataan prosenttiin.
    Koska ikkunointiympäristö ei reagoi näppäimistöön, en voi käynnistää sitä uudestaan Control + Alt + Backspace -näppäinyhdistelmällä.
    Ongelman syy
    Toimiakseen kunnolla Second Life vaatii ATIn toimittaman suljetun lähdekoodin näytönohjainajurin.
    Ratkaisu
    ATIn näytönohjainajureiden asentaminen saattaisi ratkaista ongelman, mutta en ole testannut sitä. ATIn ajurit rakentuvat vielä toistaiseksi suljetulle lähdekoodille, ja haluan pitäytyä avoimelle lähdekoodille pohjautuvissa ajureissa periaatteesta. Lisäksi työpöytätehosteet vaativat toimiakseen avoimen lähdekoodin ajurit. Avoimen lähdekoodin näytönohjainajureiden kanssa toimivaa ratkaisua ei vielä ole.
    Huomautuksia
    • Työpöydän jumiuduttua järjestelmän alasajoon voi käyttää Linux-ytimen tunnistamaa näppäinyhdistelmää Alt + SysRq + R E I S U B. Ikkunointiympäristön uudelleenkäynnistys etäyhteyden kautta saattaisi myös tehota, mutta tätä en ole testannut.
    • Second Lifen pelaaminen avoimen lähdekoodin ajureilla saattaa olla mahdollista tulevaisuudessa sikäli kuin AMD tulee lunastamaan lupauksensa avoimen lähdekoodin ajureiden toimittamisesta.
  • [Ratkaisu] Pakettienkäsittelyohjelma ja LHA-tiedosto: Arkistotyyppi ei ole tuettu

    Lähtökohta
    Kotihakemistossani on arkisto.lha -niminen, LHAlla pakattu arkistotiedosto. Haluan purkaa sen sisällön, joten avaan tiedoston Pakettienkäsittelyohjelmalla.
    Ongelma
    Pakettienkäsittelyohjelma ei näytä arkistotiedoston sisältöä, vaan seuraavanlaisen virheilmoituksen:

    Tiedoston "arkisto.lha" avaaminen epäonnistui
    
    Arkistotyyppi ei ole tuettu.
    Ongelman syy
    Lha-pakettia ei ole asennettu.
    Ratkaisu
    Asennan Synaptic-pakettienhallinnassa lha-paketin. Sen jälkeen voin avata ja purkaa LHAlla pakatun arkistotiedoston Pakettienkäsittelyohjelmalla.
  • X.org, i740 and blank console after startx

    I ran into this problem while testing X with OpenBSD 4.3: the console went completely blank after firing startx — that is, switching back to other virtual terminals while X was running would only display a black screen. And that was all I got after hitting Ctrl+Alt+Backspace from X, too: nothing but black. The command-line was still there alright, as I could blindly startx again and get X to show up, but the console terminals remained invisible until the next reboot.

    The display adapter I was using was an Intel i740 with the driver set accordingly in xorg.conf. I didn’t manage to get the video BIOS upgrading soft (Vflash.exe) from Intel to work, and never found the root cause of this problem. It was probably either the card itself or the i740 driver. I suspect that because once I swapped the card with an extra Radeon 8500LE I had laying around, and the switched to the ati driver, console VTs worked like a charm. Also, with the i740 in place they did work by using the basic vga driver, so my best bet as for the culprit would be the i740 driver.

  • How to identify a stylesheet in JavaScript

    I have been (mis)using the title attribute of stylesheets to identify and grab a specific one for further processing with my JavaScript. I did this by comparing stylesheet.title with a specified title for my embedded stylesheet. However, as I didn’t really intend the titled stylesheet to be a preferred one, once I added a title to another stylesheet higher up in the document, my other one (being lower in the document hierarchy) stopped working.

    This lead me to investigate the real significance of title, when applied to stylesheets. From what I’ve read, I have to say I’m somewhat confused by the logic with which the attribute has been named. After all, a title applied or left unapplied, to just about anything else on a web page is completely harmless, save perhaps for some decrease in the fine-tuning of your site’s accessibility. A title with relation to a stylesheet however, is so significant that HTML 4.01 categorizes stylesheets according to the presence or absence of a title. Although I don’t claim to know anything about writing specifications, I think they should have associated this categorization with the rel attribute, or at least name it differently so its significance wouldn’t get blurred by the use of title elsewhere. A stylesheet’s title‘s role would then reduced to accessory information similar to what it is when associated with, say, an a element.

    Anyway, I’ve now come up with what I at least think is a better way of identifying my embedded stylesheet. I tag the style element with an id attribute, and then compare stylesheet.ownerNode.id with whatever the string I’ve tagged it with is. I’m not sure if it’s the correct way or even whether there is one, but it seems to be working and is valid. From the specification I gather there is no id attribute associated with style in HTML 4, so it probably wouldn’t validate there. This isn’t a problem for me, since I nearly always use XHTML (Strict).

  • [Ratkaisu] Firefoxin älykkäiden kirjanmerkkien poistaminen käytöstä

    Lähtökohta
    Firefox-selaimen versio 3 on tuonut kirjanmerkkipalkkiin Älykkäät kirjanmerkit -alasvetovalikon.
    Ongelma
    En pidä älykkäitä kirjanmerkkejä tarpeellisina. Haluan ne pois haaskaamasta tilaa kirjanmerkkipalkissani.
    Ratkaisu
    Osoitan kirjanmerkkipalkin Älykkäät kirjanmerkit -kohtaa hiiren osoittimella, ja avaan ponnahdusvalikon hiiren oikeanpuoleisella napilla. Valitsen valikosta kohdan Poista, jolloin älykkäät kirjanmerkit poistuvat kirjanmerkkipalkistani.
    Mikäli myöhemmin haluan älykkäät kirjanmerkit takaisin, avaan Firefoxin asetussivun, joka on osoitteessa about:config, ja etsin sieltä asetusavaimen nimeltä browser.places.createdSmartBookmark. Asetan avaimen arvoksi false, minkä jälkeen sammutan Firefoxin ja käynnistän sen uudelleen. Tällöin Firefox luo uudestaan älykkäät kirjanmerkit kirjanmerkkipalkkiin (ja asettaa samalla browser.places.createdSmartBookmark -avaimen arvoksi true).
  • Tulostaminen Firefoxista ei toimi

    Lähtökohta
    Tulostimeni on USB-liitännän kautta tietokoneeseeni kytketty Epson Stylux C42UX. Olen ladannut siihen paperia, ja käynnistänyt sen.
    Lataan Näytön lukitseminen pikanäppäimellä -ratkaisumerkinnän Firefox-selaimeen. Haluan tulostaa merkinnän, joten valitsen Firefoxin Tiedosto-valikosta kohdan Tulosta.... Valitsen avautuvan ikkunan tulostinlistasta tulostimeni (Stylus_C42), ja määrittelen tulostusalueeksi pelkästään ensimmäisen sivun valitsemalla Tulosta sivut -otsikon alla olevan Alue-kohdan käyttöönotetuksi, ja kirjoittamalla siihen liittyvään tekstikenttään 1-1. Lopuksi painan ikkunan alalaidassa olevaa Tulosta-nappia.
    Ongelma
    Sivu ei tulostu. Sen sijaan näytölle ilmestyy otsikoton ikkuna, joka sisältää seuraavanlaisen virheilmoituksen:

    XML-jäsennysvirhe: virhe käsiteltäessä ulkoista olioviittausta
    URL: chrome://global/content/printProgress.xul
    Rivinumero 6, sarake 67:<!DOCTYPE window SYSTEM "chrome://global/locale/printProgress.dtd">
    ------------------------------------------------------------------^
    Ongelman syy
    Firefoxin suomennokset sisältävässä kielipaketissa on ohjelmavirhe, jonka takia tulostaminen ei toimi Firefoxissa.
    Ratkaisu
    Ratkaisua ei vielä ole. Ongelman voi kiertää ottamalla XULRunnerin kielipaketin pois käytöstä seuraavasti:

    1. Valitsen Firefoxin Työkalut-valikosta kohdan Lisäosat.
    2. Valitsen avautuvasta Lisäosat-ikkunasta Kielet-välilehden.
    3. Valitsen Kielet-välilehdellä olevalta listalta Xulrunner (fi) -kohdan, ja painan siihen liittyvää Poista käytöstä -nappia.
    4. Painan Lisäosat-ikkunan yläosaan ilmestyvää Käynnistä Firefox uudelleen -nappia.

    Kun tämän jälkeen otan merkinnän uudelleen esille ja kehotan Firefoxia tulostamaan sen, tulostaminen toimii.

  • [Ratkaisu] Englanninkielisen virheilmoituksen näyttäminen

    Lähtökohta
    Käyttöjärjestelmäni on suomenkielinen, eli locale-komennon antama tuloste näyttää seuraavalta:

    LANG=fi_FI.UTF-8
    LC_CTYPE="fi_FI.UTF-8"
    LC_NUMERIC="fi_FI.UTF-8"
    LC_TIME="fi_FI.UTF-8"
    LC_COLLATE="fi_FI.UTF-8"
    LC_MONETARY="fi_FI.UTF-8"
    LC_MESSAGES="fi_FI.UTF-8"
    LC_PAPER="fi_FI.UTF-8"
    LC_NAME="fi_FI.UTF-8"
    LC_ADDRESS="fi_FI.UTF-8"
    LC_TELEPHONE="fi_FI.UTF-8"
    LC_MEASUREMENT="fi_FI.UTF-8"
    LC_IDENTIFICATION="fi_FI.UTF-8"
    LC_ALL=

    Kun suoritan Päätteestä komennon ls /asdfgh, eikä hakemistoa /olematonhakemisto ole, komento antaa seuraavanlaisen virheilmoituksen:

    ls: tiedostoa /asdfgh ei voi käsitellä: No such file or directory

    Virheilmoituksen alkuosa on suomenkielinen, kuten sen kuuluu ollakin.

    Ongelma
    Suomenkielinen virheilmoitus on hakusanana paljon tehottomampi kuin englanninkielinen virheilmoitus, kun etsin ratkaisua ongelmaan. Haluan suorittaa komennon siten, että näen sen antaman virheilmoituksen englanninkielisenä.
    Ratkaisu
    Suoritan komennon siten, että nollaan kielen komennon suorittamisen ajaksi oletukseensa, seuraavasti:

    LC_ALL=C ls /asdfgh

    Tällöin komennon antama virheilmoitus näkyy kokonaan englanninkielisenä:

    ls: cannot access /asdfgh: No such file or directory

    Komennon suorittamisen jälkeen kieliasetus palautuu ennalleen, eli virheilmoitukset ja muut tulosteet näytetään jälleen suomenkielisinä.