Doppelter Symbolfehler, der const char * [] -Deklaration zugeordnet ist

7

Ich würde gerne Hilfe bei der Diagnose der Quelle eines doppelten Symbolfehlers erhalten, den ich erhalte, wenn ich versuche, mit g ++ 4.2.1 zu kompilieren.

Der spezifische Fehler ist

%Vor%

Der Fehler tritt nur auf, wenn ich diese Deklaration in eine Datei namens Parameters.h :

einfüge %Vor%

Ich habe alle meine Dateien durchsucht, und dies ist der einzige Ort, an dem SOCIODEM_FILENAMES deklariert ist. Wenn ich die Deklaration auskommentiere, verschwindet der Fehler "Duplikatsymbol".

Ich bin mit Linkerfehlern nicht vertraut (wenn das das ist) und wäre Ihnen bei der Fehlerbehebung behilflich. Alle meine Header-Dateien haben #ifndef...#define...#endif wrappers. Mein Kompilierbefehl ist

%Vor%

Vielen Dank im Voraus.

Lösungszusammenfassung

Ich habe jetzt in Parameters.h:

%Vor%

Alle anderen Definitionen und Deklarationen in Parameter.h sind unverändert. Andrey und andere Kommentatoren fassen einen alternativen Ansatz zusammen, der extern verwendet, was für meine Zwecke übertrieben ist.

    
Sarah 21.06.2010, 20:22
quelle

5 Antworten

14

Aus irgendeinem Grund hat sich bisher keine der Antworten darum bemüht, den Unterschied zwischen Ihrem Ganzzahl NUM_SOCIODEM_FILES -Objekt und dem Array SOCIODEM_FILENAMES -Objekt zu erklären. Letzteres löst den Linker-Fehler aus den bereits erläuterten Gründen aus: weil Sie Ihre Header-Datei in mehrere Implementierungsdateien einbinden. Die erste Verbindung würde jedoch ohne Probleme hergestellt (da es tatsächlich keine Probleme mit NUM_SOCIODEM_FILES declaration gibt). Warum?

Der Grund dafür ist, dass Ihr Objekt NUM_SOCIODEM_FILES zu const deklariert ist. In C ++ haben const-Objekte standardmäßig interne Verknüpfungen , was bedeutet, dass sie keine Verbindungsprobleme verursachen, selbst wenn sie in mehreren Implementierungsdateien definiert sind. Mit anderen Worten, in C ++ entspricht Ihr NUM_SOCIODEM_FILES

%Vor%

weshalb es zu keinerlei Verbindungsproblemen kommt.

Gleichzeitig wird Ihre SOCIODEM_FILENAMES nicht als Konstante deklariert, weshalb sie standardmäßig externe Verknüpfung erhält und schließlich zu Linker-Fehlern führt. Aber wenn Sie SOCIODEM_FILENAMES auch als const deklarieren, wird das Problem verschwinden.

%Vor%

Beachten Sie, wo die zusätzliche const in der Deklaration platziert wird. Wenn Sie einfach das zusätzliche const hinzufügen und alles andere unverändert belassen (dh die Definition beibehalten, wenn SOCIODEM_FILENAMES in der Header-Datei enthalten ist), wird der Linker den Fehler nicht melden, selbst wenn Sie Ihre Header-Datei in mehrere Übersetzungseinheiten einfügen / p>

Dies ist jedoch kein empfohlener Ansatz, da Sie auf diese Weise Ihre SOCIODEM_FILENAMES interne Verknüpfung angeben und eine eigenständige Kopie von SOCIODEM_FILENAMES array in jeder Übersetzungseinheit erhalten - etwas, das gut funktioniert, aber immer noch sehr wenig Sinn. Für Ihr Array ist es normalerweise besser, den in anderen Antworten empfohlenen extern -Ansatz zu verwenden.

Beachten Sie jedoch, dass Sie dies normalerweise nicht für NUM_SOCIODEM_FILES declaration tun sollten !!! Es ist in Ordnung, wie es ist, in der Header-Datei definiert. Sofern Sie nicht versuchen, etwas Ungewöhnliches zu tun, sollten skalare Konstanten normalerweise mit Initialisierer in den Header-Dateien definiert werden - so können sie als Kompilierzeitkonstanten in allen Übersetzungseinheiten angesehen werden, was sehr wertvoll ist Ding zu haben. Also, hüte dich vor dem seltsamen Ratschlag in einigen anderen Antworten, die Definition von NUM_SOCIODEM_FILES in .cpp file ebenfalls zu verschieben - das macht eigentlich keinen Sinn und ist total falsch, etwas zu tun.

    
AnT 21.06.2010, 20:59
quelle
7

Am wahrscheinlichsten ist, dass Sie diese Datei in mehreren Quelldateien enthalten. Das Problem ist, dass jede Aufnahme zu einer separaten Definition für eine Variable namens #include führt. Einschließlich Wachen helfen nicht dabei. Wächter einschließen verhindern mehrere Deklarationen innerhalb einer einzigen Kompilierungseinheit; Sie verhindern nicht mehrere Definitionen über mehrere Übersetzungseinheiten hinweg.

Sie müssen diese Variablen im Header als SOCIODEM_FILENAMES deklarieren und sie dann in genau einer Quelldatei definieren. z.B.

%Vor%

und dann:

%Vor%

Sie können damit nicht fertig werden, dies für extern zu tun, weil es eine konstante Ganzzahl ist, und der Compiler kann sie daher nur als Kompilierzeitkonstante behandeln, und sie wird niemals im kompilierten Code auftauchen. Das int kann jedoch nicht auf diese Weise behandelt werden und muss genau eine Definition haben (in C ++ als "eine Definitionsregel" bekannt).

    
Tyler McHenry 21.06.2010 20:26
quelle
2

Der Header-Guard ( #ifndef..#endif wrapper) verhindert nur, dass Sie denselben Header mehrmals in einer einzigen Quelldatei einfügen. Sie können immer noch mehrere Quelldateien mit diesem Header haben, und jeder einzelne deklariert dieses Symbol separat. Da sie alle den gleichen Namen haben, führt das Verknüpfen dieser Quellen zu einer Kollision des Symbolnamens. Wahrscheinlich möchten Sie das Symbol in einer Quelldatei anstelle einer Headerdatei deklarieren

    
Michael Mrozek 21.06.2010 20:26
quelle
2

Das Problem besteht darin, dass Sie eine Definition in eine Header-Datei einfügen. Wenn Sie diese Datei in mehr als eine Kompilierungseinheit (.cpp-Datei) einschließen, werden Sie in der Tat mehrere Definitionen erstellen und bei der Link-Zeit erhalten Sie diesen Fehler.

Sie müssen beide Definitionen in eine CPP-Datei einfügen und nur eine Deklaration in die Header-Datei einfügen:

%Vor%     
Amardeep AC9MF 21.06.2010 20:26
quelle
2

Wie andere vorgeschlagen haben, besteht eine Möglichkeit darin, NUM_SOCIODEM_FILES und SOCIODEM_FILENAMES als extern zu deklarieren und sie einmal in einer externen Datei zu definieren. Die andere Möglichkeit besteht darin, sie als static zu deklarieren - dies führt dazu, dass sie in jeder Objektdatei, die den Header enthält, dupliziert werden, aber keinen Fehler erzeugen, da die Definition für diese Objektdatei privat ist. Welche Option Sie wählen, hängt ganz von Ihren eigenen Vorlieben ab.

    
JSBձոգչ 21.06.2010 20:29
quelle

Tags und Links