Dev-C++ Linkerfehler u.a.



  • Hallo zusammen,

    ich wechsel grade von Visual Studio zu Dev-C++, und ich muss ehrlich sagen: So viele Probleme beim Umstieg hätte ich nicht erwartet (was wahrscheinlich am neuen compiler liegt, nicht an Dev-C++, denke ich jetzt mal).

    Es ist einfach so, dass ich plötzlich compiler-Fehler über code geschmissen kriege, der unter VS sauber compiliert hätte, und an dem ich einfach nicht verstehe was daran falsch sein soll.

    Problem Nummer eins:
    Singletons. Oder jedenfalls der Gebrauch derer scheint sich von MSVS zu unterscheiden. Hier mein urpsrüngliches Singleton für die GLUTApp Klasse:

    class GLUTApp {
    
      friend const GLUTApp & glutApp();
    
      [...]
    
      };
    
      inline const GLUTApp & glutApp()
      {
        static const GLUTApp theApp;
        return theApp;
      }
    
    // main.cpp
    int main( int argc, char *argv[] )
    {
      glutApp().initialize( argc, argv );
      return 0;
    }
    

    Führt zu folgendem Fehler:
    main.cpp:11: passing `const drx::GLUTApp' as `this' argument of `bool drx::GLUTApp::initialize(int, char**)' discards qualifiers

    Huh? Ich werd daraus nicht schlau, was ist falsch an dem code? Um diesen code zu compilieren muss ich den const modifier entfernen, was natürlich unklug ist, da ich eine Referenz auf ein Objekt zurückgebe, das keineswegs modifizierbar sein soll.

    Problem Nummer zwei:
    trypedef und enum scheinen in Dev-C++ anders gehandhabt zu werden. So hatte ich in meinem Wrapper für die iostream Klassen folgendes in VS programmiert:

    typedef std::ios_base::open_mode open_mode;
    typedef std::ios_base::seek_dir  seek_dir;
    typedef std::ios_base::fmtflags  format_flags;
    
    enum {
    	seekBeginning = std::ios_base::beg,
    	seekCurrent   = std::ios_base::cur,
    	seekEnd  	     = std::ios_base::end
    };
    

    Davon will Dev-C++ nichts mehr wissen. Ein typedef auf den Typ open_mode sei nicht erlaubt: 26 C:\DEVELO~1\Code\Projekte\drxlib\DrxLib\file.h
    ISO C++ forbids declaration of `open_mode' with no type

    Und: 39 C:\DEVELO~1\Code\Projekte\drxlib\DrxLib\file.h
    enumerator value for `modeReadWrite' not integer constant

    Und so weiter. Wieso funktionierts in VS, aber nicht in Dev-C++?

    Problem Nummer 3:
    Seltsame Linkerfehler. Hier habe ich glut32.lib korrekt gelinkt (über project settings, aber auch ein #pragma comment (lib, "...") hat nichts gebracht), und den header included und ich bekomme folgenden Fehler:

    [Linker error] undefined reference to `glutInit'

    im code:

    #include <GL/glut.h>
    
    bool drx::GLUTApp::initialize( int argc, char* argv[] )
    {
      ::glutInit( &argc, argv );
    
      return true;
    }
    

    Aber jetzt kommt der Hammer: Rufe ich glutInit() direkt aus der main() auf, dann bleibt der Linkerfehler aus!! Ich verzweifel hier noch.

    Kann mir bitte jemand helfen?
    Danke im Voraus.



  • matthias_k schrieb:

    ich wechsel grade von Visual Studio zu Dev-C++

    Welcher VC war's denn vorher? 6.0?

    main.cpp:11: passing `const drx::GLUTApp' as `this' argument of `bool drx::GLUTApp::initialize(int, char**)' discards qualifiers

    Huh? Ich werd daraus nicht schlau, was ist falsch an dem code? Um diesen code zu compilieren muss ich den const modifier entfernen, was natürlich unklug ist, da ich eine Referenz auf ein Objekt zurückgebe, das keineswegs modifizierbar sein soll.

    [ Das ist garantiert nicht der Original-Code. Wenn also meine folgenden, auf Raten beruhenden, Überlegungen am Kern vorbeigehen, bist du selbst schuld. ]

    initialize (die du weiter unten gepostet hast) ist eine nicht-const-Memberfunktion. Also kannst du sie nicht auf einer const-Instanz aufrufen. Keine Ahnung, warum VC++ das zulässt. Wieso machst du initialize eigentlich nicht const, ich seh da kein Hindernis?

    trypedef und enum scheinen in Dev-C++ anders gehandhabt zu werden. So hatte ich in meinem Wrapper für die iostream Klassen folgendes in VS programmiert:

    typedef std::ios_base::open_mode open_mode;
    typedef std::ios_base::seek_dir  seek_dir;
    

    Die beiden Typen heißen in Standard-C++ openmode bzw. seekdir. Warum VC++ abweicht, kann ich dir wiederum auch nicht sagen.

    Seltsame Linkerfehler.

    Da seh ich auf Anhieb nichts seltsames. Da das auch keine Frage ist, die man ohne DevC++-Wissen beantworten kann, gebe ich die an den nächsten ab 🙂



  • Welcher VC war's denn vorher? 6.0?

    .NET 2003

    [ Das ist garantiert nicht der Original-Code. Wenn also meine folgenden, auf Raten beruhenden, Überlegungen am Kern vorbeigehen, bist du selbst schuld. ]

    Wie kommst du darauf. Der über der Fehlermeldung gepostete code ist unverändert so wie er in meinem header steht.

    initialize (die du weiter unten gepostet hast) ist eine nicht-const-Memberfunktion. Also kannst du sie nicht auf einer const-Instanz aufrufen. Keine Ahnung, warum VC++ das zulässt. Wieso machst du initialize eigentlich nicht const, ich seh da kein Hindernis?

    Ganz einfach weil sie noch erweitert wird und mit Sicherheit Werte ändern wird, und da ich nicht non-stop mit mutable arbeiten möchte soll sie auch nicht const sein 🙂

    Die beiden Typen heißen in Standard-C++ openmode bzw. seekdir. Warum VC++ abweicht, kann ich dir wiederum auch nicht sagen.

    Ah super danke 🙂



  • Ich hätte da nochmal eine Frage an dich:

    Du meintest:

    initialize (die du weiter unten gepostet hast) ist eine nicht-const-Memberfunktion. Also kannst du sie nicht auf einer const-Instanz aufrufen.

    Das wusste ich gar nicht. Was birgt das denn für Gefahren dass ISO C++ es verbietet? Schliesslich mächte ich doch lediglich meine Referenz auf das globale GLUTApp Objekt konstant halten. Was kann das für Effekte auf nicht-konstante Methoden haben die ich über jene Instanz aufrufe?



  • matthias_k schrieb:

    Wie kommst du darauf. Der über der Fehlermeldung gepostete code ist unverändert so wie er in meinem header steht.

    Sorry, mein Fehler. Ich hatte glutApp() als statische Memberfunktion interpretiert. Ich hab eine Singleton-Klasse gesehen wo keine war.

    Ganz einfach weil sie noch erweitert wird und mit Sicherheit Werte ändern wird

    Dann darf eben glutApp() keine const-Referenz zurückgeben.



  • Schliesslich mächte ich doch lediglich meine Referenz auf das globale GLUTApp Objekt konstant halten.

    const GLUTApp& ist eine Referenz auf ein konstantes GLUTApp-Objekt, keine konstante Referenz. (Abgesehen davon gibt es konstante Referenzen nicht, bzw. sie sind sowieso immer konstant, je nach Sichtweise.)



  • Ja klar, du hast schon Recht, ich hab mich etwas ungeschickt ausgedrückt... Eine Referenz in C++ ist ja nur ein Aliasname für ein Objekt. Aber das beantwortet nicht meine Frage warum ich keine nicht-const Methoden über ein konstantes Objekt aufrufen kann 🙂
    Was kann da denn schiefgehen dass C++ es verbietet?!



  • Die const-Memberfunktion kann das Objekt verändern, und das verträgt sich nicht damit, dass es const ist 😉 Zur Illustration:

    class A {
        int a;
      public:
        A(int aa) a(aa) { }
        void set_a(int new_a) { a = new_a; }
        int get_a() const { return a; }
    };
    
    int main() {
      const A a1(42);
      cout << a1.get_a() << endl; // erlaubt, get_a ist const
      a1.set_a(23); // wenn das möglich wär, wozu ist a1 dann eigentlich const?
    }
    


  • Aahhh! Super danke. Verstanden 🙂

    Kann mir vielleicht noch einer wegen den Linkerfehlern helfen? Ich habs immer noch nicht hingekriegt.

    Danke.



  • Mir fällt übrigens grade ein:

    Der Konstruktor von GLUTApp ist private (sonst wäre das singleton relativ sinnlos), daher ist eine Zuweisung an glutApp() eh nicht möglich... Das const ist also geschenkt. Problem gelöst 🙂


Anmelden zum Antworten