multiple definition problem



  • Okay Leute...
    Ich habe das Gefühl Dev-Cpp will mich ärgern 😞
    Ich habe eine Zeile in meinem Code auskommentiert und trotzdem meldet mir der Compilet "multiple definition of `g_intClientsCount'"...
    Zudem ist der Fehler vollkommen unerklärlich, weil ich #ifndef nutze und das Deklarieren unter #ifndef steht.
    Hier ein Screenshot: dercoder.ohost.de/screen.jpg
    Danke sehr



  • 1. Dev-Cpp will dich definitiv ärgern, aber das hat nichts mit deinem Problem zu tun. 😉

    2. Der Fehler hat nichts mit dem Compiler zu tun und daher bringt dir das Präprozessormakro nichts. Das Problem kommt mit dem Linker. Wenn du nämlich den Header einbindest (oder wo auch immer du die Definition stehen hast), dann wird das in mehreren Quelldatein definiert, was dann die ODR verletzt. Im Header darfst du lediglich Deklarationen benutzen (von Spezialfällen, wie templates oder inline mal abgesehen).



  • Mit #ifdef (also Include Guards) kannst Du kein "multiple definition"-Fehlermeldung des Linkers beseitigen. Ich denke, dass Du das "separate compilation" Konzept noch nicht 100% verstanden hast.

    In dem Screenshot sieht man leider nicht viel. Da musst Du schon mehr Code zeigen.

    Ich schätze, Du definierst in einer Header-Datei etwas, was dann in mindestens 2 cpp-Dateien eingebunden wird. Du musst Dir das so vorstellen, dass cpp-Dateien einzeln übersetzt werden. Wenn Du nun im Header etwas definierst, dann landet die Definition per #include eventuell in mehrere "Übersetzungseinheiten". In Deinem Fall scheint das nicht erlaubt zu sein -- was auch immer g_intClientsCount ist.



  • drakon schrieb:

    Im Header darfst du lediglich Deklarationen benutzen (von Spezialfällen, wie templates oder inline mal abgesehen).

    Ich würde nicht sagen, dass struct/class-Definitionen Spezialfälle sind. :p



  • Jaja. Ich weiss. Mir gings durch den Kopf, wollte eigentlich nicht mal die Klammerbemerkung schreiben, habs dann aber doch gemacht, um ein paar krümelkacker zu begnügen. 😉 - Nicht vollständig, aber naja. Fussball ruft. 😉



  • Ja, ich benutze #include "TcpServer.h" in mehreren cpp-Dateien, undzwar weil ich einmal noch die TcpServer.cpp habe und dazu muss ich in meiner main.cpp auch die TcpServer.h include.
    Sorry, was meinst du mit ODR und so?
    Kann jemand einen Lösungsansatz posten?



  • ODR := One definition rule. Google das mal, wenn du es nicht kennst.

    Die Lösung ist einfach. Du deklarierst die Variable im Header lediglich und definierst sie in einer Quelldatei, wie man es mit Funktionen üblicherweise auch macht.

    Also:

    x.h

    extern int g_intClientsCount; // deklaration
    

    x.cpp

    int g_intClientsCount = 0; // definition
    


  • Eigentlich dürfte es keine Fehlermeldung geben, weil ich #ifndef benutze oder mach ich was falsch?
    Ich deklariere nur, sonst mach ich nichts im Header.



  • Habs mal eben angepasst. Wenn das nach dem Prinzip nicht geht poste doch einfach mal Code.



  • DerCoder schrieb:

    Eigentlich dürfte es keine Fehlermeldung geben, weil ich #ifndef benutze oder mach ich was falsch?

    Wie schon gesagt (!!) die Fehlermeldung hat mit #ifdef nichts zu tun. Aufgrund der Fehlermeldung würde ich sagen: Ja, Du machst etwas falsch. Du hast Dein g_dingsbums in mehreren Übersetzungseinheiten definiert. Davor schützt auch kein #ifdef. (!!)

    DerCoder schrieb:

    Ich deklariere nur, sonst mach ich nichts im Header.

    Aha. <seufz/> Wenn der Linker sagt, dass Du g_dingsbums mehrfach definiert hast, wird das wohl stimmen. Was willst Du jetzt hören? Offensichtlich verstehst Du das eine oder andere Konzept dahinter nicht. Es wäre zielführend, wenn Du Code zeigstest, der g_dingsbums deklariert, definiert, so dass auch klar wird, was wo per #include eingebunden wird. Dann wird man auf den Fehler/Dein Missverständnis hinweisen können und Du wirst den Fehler beheben können. Ohne relevante Codebeispiele Deinerseits kann man sich nur wiederholen: Du hast g_dingsbums mehrfach definiert. Mach dass es nicht mehr mehrfach definiert wird. Fertig.



  • TcpServer.h

    #ifndef _TCPSERVER_H
    #define _TCPSERVER_H
    
    extern int g_intClientsCount;
    
    struct ConnectionScruct
    {
    public:
        std::string szClientNickName;
        std::string szClientIp;
        SOCKET      sockClientSocket;
        sockaddr_in saClientSockAddrIn;
    } ConnStruct[16]; // <-- Hier bekomme ich auch manchmal multiple define errors.
    
    class TcpServer
    {
    // ... TcpServer-Klasse ...
    };
    
    #endif
    

    main.cpp

    #include "TcpServer.h"
    
    int main()
    {
        TcpServer tcpTcpServer(6112);
        tcpTcpServer.ServerStart();
    }
    

    Ich habe noch TcpServer.cpp. Dort include ich auch die Datei TcpServer.h und sind auch die Funktionen der Klasse.
    Das merkwürdige ist, wenn es mal multiple defininition Fehler gab, dann musste ich nur die Zeile #include "TcpServer.h" auskommentieren, dann rebuilden und wieder ent-auskommentieren, funktioniert es. Dann von einem compilen zum anderen, wieder nicht 😞 Es geht nicht in meinen Kopf rein.
    Wofür steht extern?



  • Genau gleicher Fehler. Überleg nochmal, was wir dir bereits mehrmals gesagt haben..



  • Ich sehe bei Dir nirgendswo eine Definition von g_intClientsCount.

    DerCoder schrieb:

    TcpServer.h

    #ifndef _TCPSERVER_H
    #define _TCPSERVER_H
    
    extern int g_intClientsCount;
    
    struct ConnectionScruct
    {
    public:
        std::string szClientNickName;
        std::string szClientIp;
        SOCKET      sockClientSocket;
        sockaddr_in saClientSockAddrIn;
    } ConnStruct[16]; // <-- Hier bekomme ich auch manchmal multiple define errors.
    

    Das ist auch zu erwarten, wenn Du diesen Header in mehr als einer cpp-Datei einbindest; denn Du definierst hier ein statisches Array mit Namen ConnStruct . Das extern int g_intClientsCount; ist übrigens eine Deklaration. Mach Dich nochmal schlau über die Unterschiede zwischen Deklaration und Definition. Das steht in jedem C++ Buch drin, was etwas auf sich hält.

    DerCoder schrieb:

    Wofür steht extern?

    Steht im schlauen C++ Buch drin. In diesem Fall führt es dazu, dass die Zeile nur eine Deklaration einer globalen Variablen, nicht aber eine Definition ist. Das wurde hier aber auch schonmal erwähnt. Wer lesen kann ... Du kannst Die Begriffe ja auch mal bei Google probieren. Das soll ja abundzu funktionieren, habe ich gehört. 😃



  • x.h
    extern int g_intClientsCount; // deklaration

    x.cpp
    int g_intClientsCount = 0; // definition

    Sorry, ich verstehe nicht, was ich mehrfach definiere -.-



  • In meinem Code wird nichts mehr mehrfach definiert.

    Mach dir einfach klar, dass eine Variablendeklaration im globalen Bereich auch eine Definition ist (ausser man hat da extern noch dran stehen, was dann sagt, dass die Variable irgendwo anderst definiert wird; in unserem Fall in der gezeigen .cpp).

    Wenn du das in einem Header hast und den mehrmals inkludierst, dann hast du praktisch (mehr oder weniger) das hier stehen:

    int n = 2;
    //...
    int n = 5;
    

    Was natürlich Mist ist.


Log in to reply