webentwicklung-frage-antwort-db.com.de

"Mehrfachdefinition des C++ - Compiler-Fehlers

Ich scheine diese scheinbar zufälligen Kompilierungsfehler in einer meiner Klassen nicht zu beseitigen. Ich bekomme ungefähr 4 Fehler wie:

multiple definition of `draw_line(float, float, float, float)'

und

multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'

die in der Mitte der Methode markiert sind.

Ich bekomme auch ständig multiple definition of `stack' in der Mitte einer anderen Methode. stack ist eine globale Variable in einer völlig anderen Datei. Es wird nicht einmal in der Datei erwähnt, in der der Fehler angezeigt wird.

Ich habe versucht, die fehleranfällige Datei in .h- und .cpp-Dateien zu trennen (war ursprünglich nur eine .cpp-Datei) und nichts an dem Fehler hat sich geändert ...

Ich habe keine doppelten Methoden. Ich habe nur einen #include von lines.h und am Anfang gibt es eine #ifndef-Klausel. Alle diese Fehler werden in der CPP-Datei angezeigt.

Irgendwelche Ideen was es sein könnte?

Okay, ich habe den Code aufgeschaltet:

Die lines.cpp-Datei ist eine konvertierte .c-Datei, die ich von meinem Lehrer erhalten habe. Ich habe das Makefile für alle Fälle hinzugefügt, weil ich immer Probleme damit habe. Ich habe auch kommentiert, wo die Fehler in der Datei markiert waren, aber sie scheinen ziemlich zufällig zu sein, daher weiß ich nicht, ob es besonders wichtig ist. Ich habe die .h-Datei aufgegeben, weil sie nichts gelöst oder geholfen hat. Ich glaube, es wird leichter sein, den Fehler ohne ihn zu finden.

Hier ist die angeforderte main.cpp-Datei (es gibt keine .h).


Ich habe die Datei lines.h wegen neu erstellt und bekomme immer noch die:

multiple definition of `draw_line(float, float, float, float)'

und

multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'

fehler in der Datei lines.cpp, aber der multiple definition of `stack'-Fehler befindet sich jetzt an einer zufälligen Stelle in der Datei ThreeD.cpp (und ist jetzt mit einem Kommentar gekennzeichnet). Update: Dieser Fehler wurde behoben und die Dateien wurden überarbeitet, um dies anzuzeigen:

Ich habe mich damit beschäftigt, einige globale Variablen extern zu kennzeichnen, aber es schien nichts zu beeinflussen.

14
Chad

Warum enthalten Sie lines.cpp in ThreeD.cpp? Das ist sehr ungewöhnlich.

Ihr Makefile will lines.o, also kompilieren Sie lines.cpp. Alles, was in lines.cpp definiert ist, wird in lines.o und auch in ThreeD.o stehen.

In lines.cpp gibt es einen interessanten Kommentar:

Don't forget to put declarations in your .h files. 

Ich denke, der Lehrer möchte, dass Sie lines.cpp in eine .h und eine .cpp aufteilen.

Auszug aus lines.cpp:

/* These go in your .h file or in lines.h */
/*

Line drawing header.

*/


void draw_line(float, float, float, float);
int near_far_clip(float, float, float *, float *, float *, float *,
                  float *, float *);

Ich vermute, dass diese beiden Erklärungen das Einzige sind, was in Zeilen stehen sollte.

14

Sie enthalten wahrscheinlich die Funktionsdefinitionen in einer Header-Datei. Fügen Sie das Schlüsselwort inline hinzu, damit sie nicht von jeder Objektdatei exportiert werden, oder legen Sie sie in einer eigenen .cpp-Datei ab.

Für Ihre globale Variable müssen Sie das Schlüsselwort extern in Ihrer Headerdatei verwenden. Andernfalls exportiert jede Objektdatei ihre eigene Variable, und der Linker wird verwirrt, welche davon korrekt verwendet wird.

34
strager

Bitte posten Sie einige Code-Schnipsel. Vielleicht definieren Sie Ihre Methoden sowohl in der Klassendeklaration als auch außerhalb?

class X {
    void foo();    // No definition, just declaration
    void bar() {}  // Declaration + definition
};

void X::foo() {}    // First Definition, OK
void X::bar() {}    // Already defined, ERROR
3
Ferdinand Beyer

Überprüfen Sie, ob die Schutzeinrichtungen falsch geschrieben sind.
Überprüfen Sie Ihre Einrichtungsoptionen. Vielleicht hat jemand aus mehreren Objektdateien zusammengestellt.
Versuchen Sie, Teile von Dateien und Code auszuschließen, bis Sie keine Fehlerursache finden. 

BEARBEITET:
Fix enthalten * .cpp-Dateien. Sie sollten verlinkt werden.

3
bayda

Wie gesagt - nicht genügend Informationen, um hier richtig zu diagnostizieren.

Wenn draw_line et al jedoch nicht in einer Quellendatei (cpp-Datei), sondern in einer Headerdatei definiert sind, gibt es möglicherweise Methoden, die in der Headerdatei als Inline deklariert sind und die eigentlich nicht wirklich Inlining sind. In diesem Fall generiert jede .cpp-Datei, die den Header enthält, ihre eigene Definition der draw_line-Funktion und generiert Warnungen zum Zeitpunkt der Verknüpfung.

Dies kann vorkommen, wenn Sie ein #defined INLINE-Makro verwenden, das aus einem vergessenen oder entfernten Systemheader stammt, und aus welchem ​​Grund auch immer, dass die INLINE zu nichts verarbeitet wird.

Z.B.:

//Lines.h

#define GCCC //Note the typo

#if defined(GCC)
#define INLINE inline
#Elif defined (MSVC)
#define INLINE __inline
#else

#define INLINE //Due to the typo, INLINE will be turned into nothing
#endif

INLINE void draw_line(float x1, float y1, float x2, float y2)
{
   //Draw the line
}

//File1.cpp
#include "lines.h" //will define draw_line

//File2.cpp
#include "lines.h" //will also define draw_line

Durch das Verknüpfen von File1.cpp und File2.cpp werden mehrere Deklarationsfehler generiert

3
MrCranky
#ifndef THREED_H_
#define THREED_H_
#endif /* THREED_H_ */

löschen oder kommentieren Sie diese Zeilen und das hat für mich funktioniert 

2
Gaurav Maan

Mehrere Definitionsfehler sind Linker-Fehler, aber ohne weitere Informationen ist es schwierig, sie zu diagnostizieren. Stellen Sie sicher, dass dieselbe Datei nicht zweimal im Linkerbefehl angezeigt wird und dass Ihre Header-Dateien nur Deklarationen und keine Definitionen enthalten.

1
anon

Ohne den Code zu sehen, hilft Ihnen wirklich nichts. Der Compiler behauptet eindeutig das Gegenteil von Ihnen (dort ist mindestens eine doppelte Definition).

Versuchen Sie, den Fehler mit einem minimalen Beispiel zu reproduzieren. Haben Sie versucht, den Code außerhalb von Eclipse in der Befehlszeile zu kompilieren? Mit welchem ​​ergebnis

1
Konrad Rudolph

Hi, was ich hier sehe, dass die Grundregel für ll gilt. Ich werde erklären, wie die Dinge in dieser Art von Fehlern funktionieren und was auch immer das ist: Nehmen wir ein Beispiel von "Eine globale Variable erstellen"

Verwechseln Sie die Header-Datei nicht für eine CPP-Datei. Der Header dient nur dazu, dass mehrere Dateiprojekte vor dem Linken eine gemeinsame - Schnittstelle Haben.

1.Listenelement

Sie sollten Informationen über die globale Variable im Header angeben:

extern int Var_Global;

  1. Listenpunkt

    while keeping the Actual code in the
    cpp :
    
    int Var_Global;
    

Stellen Sie sicher, dass Sie 1. den Header hinzufügen und 2. den Code verknüpfen.

Verknüpfen Sie den Code einmal und nur einmal, und es gibt nur eine Kopie der Daten, . Wenn Sie jedoch den ganzen Tag Kopfzeilen einschließen können, wird dem anderen Code mitgeteilt, dass Eine Kopie davon enthält die Daten zum Zeitpunkt der Verbindung.

Ich sehe eine Menge Leute, die Code in Header-Dateien einfügen, obwohl dies in einigen Fällen (....) Funktionieren kann. Es ist eine schlechte Angewohnheit, darauf einzugehen, und wird früher oder später Probleme bereiten.

Grüße,

Prashanta