Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

  • »Johannes Schneider« ist der Autor dieses Themas

Beiträge: 103

Beruf: Chemiestudent

  • Private Nachricht senden

1

22.03.2014, 15:23

MSVC: Mehrfachdefinition in Objektdatei

Hallo.

Bisher hab ich es immer gemieden, Quellcode "sauber" in .h und .cpp Dateien zu trennen.
Ich habe stets Headerdateien mit vollständigem Code verwendet und war glücklich damit.
Aber ich denke das ist nicht richtig.

Bloß kriege ich die Hierachie der Dateien einfach nicht unter Kontrolle.
Das ist mein bisheriges kleines Projekt:


(Link)


Beim Linken dann diese Meldung:


(Link)


Mit vorkompilierten Headerdateien kommt das selbe Problem
Vom Projekt ausschließen bringt auch nichts.
Und das "Allheilmittel" #pragma once hilft hier nicht :(

Danke für jede Hilfe.
Vielleicht ein Thema für die FAQ, ich hab kein ähnliches finden können...


**EDIT**
Ich hab vergessen zu erwähnen, was EVENTNAMES, MONTHS usw. sind:


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// event names enumeration
const char * EVENTNAMES[] = {
    "INFO", "WARNING", "ERROR", "FATAL ERROR"
};


// months enumeration
const char * MONTHS[] = {       
    // index 0 is undefined
    "UNDEFINED", "Jan", "Feb", "Mar", "Apr", "May",
    "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};


// weekday enumeration
const char * WEEKDAYS[] = {
    "Sun", // sunday = 0
    "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
"Das Glück des Forschers besteht nicht darin, die Wahrheit zu besitzen, sondern eine Wahrheit zu erringen. Und in diesem fortschreitendem, erfolgreichen Suchen nach der Wahrheit - darin liegt die
eigentliche Befriedigung." Max Planck

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Johannes Schneider« (22.03.2014, 15:29)


Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

2

22.03.2014, 16:01

Interessant wäre noch wo EVENTNAMES usw. deklariert sind. In einer Headerdatei? Dann müssen die als extern gekennzeichnet sein.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

  • »Johannes Schneider« ist der Autor dieses Themas

Beiträge: 103

Beruf: Chemiestudent

  • Private Nachricht senden

3

22.03.2014, 16:15

ja, EVENTNAMES usw. sind in types.h deklariert, doch auch die Kennzeichnung als "extern" bringt immernoch denselben Fehler.
Wieso müsste ich die als extern kennzeichnen, wenn ich types.h doch sowieso in logfile.h einbinde? sind diese dann nicht sowieso schon verfügbar?
"Das Glück des Forschers besteht nicht darin, die Wahrheit zu besitzen, sondern eine Wahrheit zu erringen. Und in diesem fortschreitendem, erfolgreichen Suchen nach der Wahrheit - darin liegt die
eigentliche Befriedigung." Max Planck

4

22.03.2014, 16:30

Versuch mal, deine Konstanten in einem anonymen Namespace einzuschließen, etwa so:

C-/C++-Quelltext

1
2
3
4
namespace
{
    static const int EVENTNAMES = 0;
}


Ich kann dir nicht genau sagen, womit das zusammenhängt, aber ich hatte dieses Problem auch einmal in einer Header-Datei.

Ich hoffe, das hilft.

Liebe Grüße,
~ EuadeLuxe ~

  • »Johannes Schneider« ist der Autor dieses Themas

Beiträge: 103

Beruf: Chemiestudent

  • Private Nachricht senden

5

22.03.2014, 16:39

hmm. Das hilft leider auch nicht.
Die Objekte sind immernoch "doppelt" definiert :(

Ich habs alle Typen in types.h nun unter ein namespace gestellt. Nun kommt der Fehler nicht mehr beim Linken, sondern beim Kompilieren:


1>f:\dokumente\visual studio 2010\projects\opengl\logfile.h(74): error C2374: 'Hanni::EVENTNAMES': Neudefinition; Mehrfachinitialisierung
1> f:\dokumente\visual studio 2010\projects\opengl\types.h(41): Siehe Deklaration von 'Hanni::EVENTNAMES'
1>f:\dokumente\visual studio 2010\projects\opengl\logfile.h(80): error C2374: 'Hanni::MONTHS': Neudefinition; Mehrfachinitialisierung
1> f:\dokumente\visual studio 2010\projects\opengl\types.h(47): Siehe Deklaration von 'Hanni::MONTHS'
1>f:\dokumente\visual studio 2010\projects\opengl\logfile.h(88): error C2374: 'Hanni::WEEKDAYS': Neudefinition; Mehrfachinitialisierung
1> f:\dokumente\visual studio 2010\projects\opengl\types.h(55): Siehe Deklaration von 'Hanni::WEEKDAYS'
1> logfile.cpp
1>f:\dokumente\visual studio 2010\projects\opengl\logfile.h(74): error C2374: 'Hanni::EVENTNAMES': Neudefinition; Mehrfachinitialisierung
1> f:\dokumente\visual studio 2010\projects\opengl\types.h(41): Siehe Deklaration von 'Hanni::EVENTNAMES'
1>f:\dokumente\visual studio 2010\projects\opengl\logfile.h(80): error C2374: 'Hanni::MONTHS': Neudefinition; Mehrfachinitialisierung
1> f:\dokumente\visual studio 2010\projects\opengl\types.h(47): Siehe Deklaration von 'Hanni::MONTHS'
1>f:\dokumente\visual studio 2010\projects\opengl\logfile.h(88): error C2374: 'Hanni::WEEKDAYS': Neudefinition; Mehrfachinitialisierung
1> f:\dokumente\visual studio 2010\projects\opengl\types.h(55): Siehe Deklaration von 'Hanni::WEEKDAYS'
1> Code wird generiert...


Binde ich "types.h" in logfile.h nicht ein, so findet der Compiler die Typen in aus types.h nicht (logisch)...
"Das Glück des Forschers besteht nicht darin, die Wahrheit zu besitzen, sondern eine Wahrheit zu erringen. Und in diesem fortschreitendem, erfolgreichen Suchen nach der Wahrheit - darin liegt die
eigentliche Befriedigung." Max Planck

6

22.03.2014, 20:39

Laut der MSDN wird dein Fehler dann ausgegeben, wenn ein Objekt (z.B. eine statische Variable) mehrfach initialisiert wird.

Gründe, die mir jetzt einfallen, wären:
  1. Include-Guard vergessen.
  2. Statische / Globale Variable mehrfach initialisiert.
  3. Globale Variable in einem Header definiert, statt sie als extern zu kennzeichnen, oder in einen anonymen Namespace einzubinden.

Mehr wüsste ich jetzt auch nicht.
Evtl. liegt der Fehler in deinem EVENTNAMES-Array. Versuch doch mal, eine Datei namens 'types.c(pp)' zu erstellen, welche 'types.h' inkludiert, und welche die eig. Definition enthält. In 'types.h' schreibst du dann:

C-/C++-Quelltext

1
extern const char* EVENTNAMES;


Ich hoffe, das hilft.
Liebe Grüße,
~ EuadeLuxe ~

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

22.03.2014, 22:38

Include Guards können da gar nichts ausrichten. Wenn Variablen in einem Header definiert werden, werden sie in jeder .cpp definiert, die diesen Header einbindet. Und damit existieren sie eventuell mehrfach.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

  • »Johannes Schneider« ist der Autor dieses Themas

Beiträge: 103

Beruf: Chemiestudent

  • Private Nachricht senden

8

23.03.2014, 16:09

Include Guards können da gar nichts ausrichten. Wenn Variablen in einem Header definiert werden, werden sie in jeder .cpp definiert, die diesen Header einbindet. Und damit existieren sie eventuell mehrfach.

Ja aber sollte


C-/C++-Quelltext

1
2
3
4
5
6
#ifndef EINGEBUNDEN
#define EINGEBUNDEN

// code

#endif


nicht genau das verhindern?
Egal was ich auch mache das Zeugs ist und bleibt bereits woanders definiert :(


**EDIT**
wenn ich #include "logfile.h" ein main.cpp weglasse verschwindet der Fehler..
Nur kann ich dann eben keine Logdateikasse in main.cpp instanzieren...
"Das Glück des Forschers besteht nicht darin, die Wahrheit zu besitzen, sondern eine Wahrheit zu erringen. Und in diesem fortschreitendem, erfolgreichen Suchen nach der Wahrheit - darin liegt die
eigentliche Befriedigung." Max Planck

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

23.03.2014, 16:28

Nein. Das verhindert nur, dass ein Header mehrmals pro Compile-Einheit eingebunden wird. Hast Du nun aber z.B. eine "Main.cpp" und eine "Foo.cpp" und bindest in beiden den Header "Log.h" ein und in diesem wird eine Variable definiert, so findet der Linker sie dann in den beiden Modulen für Main und für Foo als definiert vor, denn jede Einheit für sich hat die Definition über den Header eingebunden. Da hilft kein Include-Guard und für solche Fälle ist es auch gar nicht gedacht. Das führt letztlich dann zu einem Linker-Fehler.
Ausweg ist hier über "extern". Du deklarierst im Header "Log.h" eine Variable und definierst diese dann erst in "Log.cpp".
Ohnehin ist es deutlich eleganter, wenn Du keinen String-Array für verschiedene Log-Typen definierst, sondern wenn Du stattdessen ein Enum verwendest.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

  • »Johannes Schneider« ist der Autor dieses Themas

Beiträge: 103

Beruf: Chemiestudent

  • Private Nachricht senden

10

23.03.2014, 16:34

Ok Die Lösung des Problems ist:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    // event names enumeration
    const char * EVENTNAMES[] = {
        "INFO", "WARNING", "ERROR", "FATAL ERROR"
    };

    // months enumeration
    const char * MONTHS[] = {       
        // index 0 is undefined
        "UNDEFINED", "Jan", "Feb", "Mar", "Apr", "May",
        "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    };

    // weekday enumeration
    const char * WEEKDAYS[] = {
        "Sun", // sunday = 0
        "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
    };


usw. direkt in logfile.cpp einzubinden.
Ich habe keine Ahnung, warum der Linker sich über diese Arrays beschwert, nicht aber über die Enumerationen der Fehlertypen. Die müssten auch doppelt vorkommen.
Naja danke :)
"Das Glück des Forschers besteht nicht darin, die Wahrheit zu besitzen, sondern eine Wahrheit zu erringen. Und in diesem fortschreitendem, erfolgreichen Suchen nach der Wahrheit - darin liegt die
eigentliche Befriedigung." Max Planck

Werbeanzeige