Linker -> undefined reference



  • Hi,

    ich bin recht neu in der Linuxwelt und kämpfe mich so eingermaßen durch,
    meine aber die Kompilierschritte und das Linken halbwegs verstanden zu haben.

    Nun komme ich aber nicht weiter und bin für jeden Hinweis dankbar...

    Ich habe folgende Klasse BodyForce nur auf den Konstruktor reduziert.

    body_force.hpp:

    // ********** includes **********
    #include<base/function.h>
    
    namespace ares
    {
        namespace boundaries
        {   
            template <int dim>
            class BodyForce : public dealii::Function<dim>
            {
                public:
                    // ***** constructors ****
                    BodyForce();    
            }; // class BodyForce
    
        } // namespace boundaries
    
    } // namespace ares
    

    body_force.cpp:

    // ********** includes **********
    #include<boundaries/body_force.hpp>
    
    // ********** using declarations **********
    using namespace ares;
    using namespace boundaries;
    using namespace dealii;
    
    template<int dim>
    BodyForce<dim>::BodyForce()
                        :
                        Function<dim> (dim)
    {
    } // constructor
    

    und es soll nur der Konstruktor getestet werden
    test_body_force.cpp:

    // ********** includes **********
    #include <boundaries/body_force.hpp>
    
    // ********** using declarations **********
    using namespace ares;
    using namespace boundaries;
    
    int main()
    {
        const int dim = 2;
        BodyForce<dim> aBodyForce;
    
        return 0;
    }
    

    So eigentlich nix wildes, nun kompliere ich mit

    g++ -c test_body_force.cpp body_force.cpp -I../../include -I/cluster/deal/deal.II/base/include
    

    und es kommt keine Fehlermeldung

    Wenn ich dann aber linken will mit

    g++ -o test.out test_body_force.o body_force.o -L/cluster/deal/deal.II/lib -lbase.g
    

    kommt folgende Fehlermeldung

    test_body_force.o: In function `main':
    test_body_force.cpp:(.text+0x15): undefined reference to `ares::boundaries::BodyForce<2>::BodyForce()'
    collect2: ld returned 1 exit status
    

    und das checke ich nicht, denn ich hab ja body_force.o erstellt und auch an den Linker übergeben, warum findet der dann nicht den zugehörigen Konstruktor...

    Daher bin ich für jede Idee dankbar

    Gruß
    Rahul



  • BodyForce ist keine Klasse, sondern eine Klassenvorlage. Die Vorlage muss dem Compiler vollständig bekannt sein, um nach Bedarf Klassen daraus konkretisieren zu können - das heißt, du kannst sie nicht wie eine Klasse in Header- und Quelldatei aufspalten.

    Pack die Definition des Konstruktors auch in den Header, und das Problem sollte verschwinden.



  • Danke für den Hinweis,
    das kommt davon, wenn man Templates zwar oft genutzt,
    aber so gut wie nicht selbst programmiert hat...

    Allerdings möchte ich ungern alles in eine Header-Datei
    (empfinde ich als unschönen Stil) packen.

    Nach ein wenig Googlen finde ich auch andere Wege,
    insbesondere als Stichworte:
    -Modell der einschließenden Kompilierung
    -Modell der getrennten Kompilierung

    Was ich aber nicht so genau gefunden habe,
    ist den Nachteil der getrennten Kompilierung...

    Der Nachteil der einschließenden Kompilierung war der eventuell
    unnötiger mehrfacher Instanzierung bei bestimmten Compilern.

    Hat dazu jemand eine Antwort.

    Vielen Dank
    Rahul


Anmelden zum Antworten