Objektorienterad Programkonstruktion

2D1947 Objektorienterad Programkonstruktion

Lösningar på de vanligaste praktiska problemen

Fel vid kompilering och länkning

  1. Varför klagar make på att den inte hittar regler för att skapa vissa include-filer?

    Kolla om det ingår siffrorna "2.6.3" i namnet på den saknade include-filen. I så fall är antagligen de hjälpfiler som make skapar för gamla (Elektro har bytt till gcc 2.7.0). Gör make clean och sedan make igen.

  2. Varför klagar gcc/g++ 2.7.0 (just nu, 95-08-11, endast installerad på Elektro under OSF) på att i är odefinered efter slingan i följande kodavsnitt:
        for (int i=0; i<10; i++)
            cerr << i;
        cerr << i; // ERROR: i undefined
    

    Enligt senaste standardförslaget för C++ ska i vara lokalt definierad i slingan, och det implementerar gcc 2.7.0. Vill man kunna använda dess värde efter slingan måste man numera flytta ut definitionen utanför slingan:

        int i;
        for (i=0; i<10; i++)
            cerr << i;
        cerr << i; // OK
    
    Detta innebär också att koden
        for (int i=0; i<10; i++)
            cerr << i;
        for (int i=0; i<10; i++)
            cerr << i;
    
    numera går igenom. (Förut blev i multipelt definierad.)

  3. Varför kraschar ibland Sun CC med ett "assertion failed in prepexpression.cc"?

    Det ska den givitvis inte göra. Det är en kompilatorbugg. Buggen visar sig dock bara om ditt program innehåller vissa speciella syntaxfel. Ett av dem är att skriva något i stil med

    template<class T> X::f() {
        return Y;
    }
    
    istället för
    template<class T> X::f() {
        return Y<T>;
    }
    
    där X och Y båda är mallklasser parametriserade på typen T.

  4. Vaför får jag plötsligt ett felmeddelande vid länkningen trots att mitt program gick utmärkt att kompilera och länka igår och jag inte har ändrat något sedan dess?

    Då och då fixar jag buggar i kursbiblioteket (jodå, sådana finns...). Ibland blir jag tvungen att ändra gränssnittet. Använder man make är det dock inget problem, eftersom make upptäcker att .hh-filen är ändrad och kompilerar om det som behöver kompileras om. Men om du har kopierat en massa .hh-filer från kurskatalogen till din egen katalog, kommer dessa att vara föråldrade och inkompatibla med biblioteksfilen efter buggfixen.

    Alltså: Kopiera inte filer från kurskatalogen i onödan! Det gäller generellt, inte bara på denna kurs.

  5. Varför får jag en massa konstiga felmeddelanden när jag växlar mellan Alpha (OSF) och Ultrix-maskiner?

    Se till att du har rätt version av Makefile. Lämpliga makefiler finns alltid under $OOPKHOME/makefiles/oopk-lab*, men kom ihåg att $OOPKHOME pekar på olika kataloger på olika maskiner. Rensa också bort gamla *.o- och *.d-filer med make clean när du har växlat maskintyp.

  6. Varför klagar g++ på syntaxfel när jag använder en iteratortyp ur FCL i en egen klassmall, t ex
    template<class T> class MyClass {
        void f(List<T>::Iter i);
        // ...
    };
    

    Detta är en känd bug i g++. Det är inget fel med konstruktionen ovan. Man kan dock undvika denna kompilatorbug genom att byta ut List<T>::Iter mot Iterator<List<T>, ListNode_*, T> och Vec<T>::Iter mot Iterator<Vec<T>, size_t, T> där g++ klagar.

  7. När länkaren klagar på att symboler är odefinierade, varför ser namnen på dem så kryptiska ut?

    Eftersom C++ tillåter att flera funktioner har samma namn måste kompilatorn på något sätt koda in parametrarnas typ i de symboler den skickar till länkaren. För program kompilerade med g++ kan du använda hjälpprogrammet c++filt för att få ut funktionsnamnen i klartext. Exempel:

    /usr/ucb/ld:
    Unresolved:
    set__6MatrixUiUiRCd
    
    zafir> echo set__6MatrixUiUiRCd | c++filt
    Matrix::set(unsigned int, unsigned int, double const &)
    

    Tips: Om du kompilerar innefrån Emacs med M-x compile dyker felmeddelandena från länkaren upp i en Emacs-buffert. Om du markerar namnen på de odefinierade symbolerna där och ger kommandot M-x shell-command-on-region och därefter anger c++filt hamnar alla symbolnamnen i klartext i en ny Emacs-buffert.

  8. Varför blir vissa medlemsfunktioner i Complex multipelt definierade när jag kompilerar med g++?

    Det nuvarande versionen av standardbiblioteket till g++ innhåller en klass som råkar heta just Complex! Om man inte har definierat alla medlemsfunktioner i sin egen Complex-klass kommer länkaren att dra in funktioner från standardbiblioteket, vilka i sin tur drar med sig funktioner som man har definierat (och som då rapporteras som "multiply defined"). Lösningen är

    1. att se till att alla funktionsmedlemmar verkligen definieras, och om det inte skulle hjälpa,
    2. att döpa om klassen till något annat, t ex Complex2 (du kan använda Emacs-kommadot M-% för det).

  9. Varför klagar Suns kompilator/länkare på mina mallklasser trots att jag har fixat felen i dem?

    Suns kompilator lägger klasser och funktioner den har genererat från mallar på underkatalogen Templates.DB. Ibland tappar kompilatorn bort sig när du ändrar mycket i mallarna. Pröva att ta bort de genererade klasserna och funktionerna med make clean och bygg sedan om alltihopa med make.

  10. Varför får jag följande felutskrift från länkaren på Elektros Alpha-maskiner:
    /usr/ucb/ld:
    Archive: /home/guests/harald/Public/oopk/1.0/ultrix44gcc263/lib/libfcl.a 
    has no table of contents (not searched)
             add one with 'ar ts'
    Unresolved:
    	...
    

    Troligen har du modulen oopk-ef/ultrix-gcc inladdad trots att du kör på en Alpha (med operativsystemet OSF). Växla till modulen oopk-ef/osf-gcc. Om du laddar modulen med module load oopk-ef95 ska du automatiskt få en modul som passar för den maskin du kör på.

    Fel vid avlusning

    1. Varför kan jag inte starta debugger på NADA:s maskiner? (Felmeddelandet rör oftast ToolTalk.)

      Gör

      	module load openwin
      
      och försök igen.


      harald@nada.kth.se