Warum kann ich nicht einfache C-Funktionen in der Header-Datei definieren?

8

Ich erhalte immer einen Build-Fehler, wenn ich versuche, eine C-Funktion in der Header-Datei direkt über der Schnittstelle der Klasse zu definieren.

aber wenn ich das gleiche in der Implementierungsdatei mache und eine Deklaration in der Kopfzeile gebe. Die Dinge funktionieren.

Ich wollte wissen, warum es so ist, weil ich enums, structs, konstante NSStrings in der Header-Datei definiert habe, also warum funktioniert C nicht?

    
Amogh Talpallikar 20.04.2012, 07:57
quelle

1 Antwort

14

Dies hat damit zu tun, wie der C-Linker (oder Link-Editor) funktioniert. Wenn der C-Compiler auf eine Funktionsdefinition stößt, bereitet er den Assembler-Code vor, der diese Funktion implementiert, und markiert ihn mit einem -Symbol , das zum Linker sagt: "Hier beginnt die Funktion mit diesem Namen". Das Symbol wird normalerweise mit einem Unterstrich gefolgt von dem Funktionsnamen, z.B. _printf .

Wenn Sie die Funktion in einer Headerdatei definieren, kompiliert jede .c oder .m -Datei, die diesen Header importiert, die Funktion und bewirkt, dass der Compiler dasselbe Symbol ausgibt. Der Linker erwartet, nur eine Instanz jedes Symbols zu finden, also ist dies ein Fehler.

Dies hängt nicht mit der Existenz von #include guards oder der Verwendung von #import anstelle von #include zusammen. Der C-Compiler arbeitet an einzelnen Übersetzungseinheiten - womit er einzelne Quelldateien meint. Präprozessor-Strategien verhindern, dass Sie dieselbe Header-Datei zweimal in eine einzelne Quelldatei aufnehmen, aber nichts tun, um Aktivitäten über mehrere Dateien hinweg zu koordinieren. Das bedeutet, dass es zulässig ist, die gleichen Header in verschiedene Quelldateien einzufügen. Das bedeutet auch, dass sie beim Kompilieren verschiedener Dateien (legal) das gleiche Symbol enthalten können.

Es ist die Aufgabe des Linkeditors, diese Dateien zusammenzufassen und alle Verweise auf Symbole aufzulösen, die zum Zeitpunkt der Kompilierung unbekannt waren. Wenn Sie versuchen, Objekte (den Namen von kompilierten und assemblierten Übersetzungseinheiten) mit demselben Symbol in dasselbe Archiv, dieselbe Bibliothek oder dieselbe ausführbare Datei zu verknüpfen, erhalten Sie den Fehler, den Sie hier sehen.

Lösungen:

  • Definieren Sie die Funktion nicht im Header, deklarieren Sie sie einfach dort und definieren Sie sie in einer Implementierungsdatei. wie du bereits herausgefunden hast, funktioniert das.
  • Definieren Sie die Funktion in der Kopfzeile, aber schließen Sie diese Kopfzeile nur an einer Stelle in Ihrem Code ein. Dies ist oft aus gestalterischen Gründen nicht akzeptabel.
  • Definieren Sie die Funktion in der Kopfzeile mit dem Modifikator inline . Inline-Funktionen werden vom Compiler nur in die Funktion kopiert, in der sie aufgerufen werden. Daher wird für sie kein Linkersymbol ausgegeben. Dies hat seine eigenen Kompromisse, die Sie lesen möchten mehr über .
user23743 20.04.2012, 08:06
quelle

Tags und Links