extern Deklaration
-
Guten Abend,
weiss jemand, welchen Grund es geben kann, eine Funktion im einem Headerfile als extern zu deklarieren, also zB
extern double umrechnung(int);
-
eigentlich gibt es keinen Grund bei Funktionen extra auf das 'extern' hinzuweisen, afaik ist das 'extern' bei Funktionen implitzit da.
Bei Variablen ist es natürlich wichtig, sonst wird sich der Linker mit multiple definitions melden.
edit: furchtbar, so viele Schreibfehler in den letzten 5 Minuten hatte ich noch nie
-
wieso würde der Compiler multiple definitions melden? Also, vorausgesetzt, die Variable würde tatsächlich nur in den Headerfile deklariert.
together.hint n; int test(void);
main.c
#include <stdio.h> #include "together.h" int main (int argc, vhar * argv[]) { n = 3; return 1; }
snd.c
#include <stdio.h> #include "together.h" int test (void) { printf("%d\n",n ); return 1; }
gcc main.c snd.c
müsste doch gehen, oder?
-
Deklarationen an sich schaden nicht, nur mehrfache Definitionen führen zu einem Fehler. Stichwort: "one definition rule". Natürlich musst du die Variable trotzdem irgendwann vor Verwendung initialisieren.
Das Schlüsselwort "extern" zeigt lediglich eine Referenz auf die Definition einer globalen Variable an, die erst beim Linken aufgelöst wird.
-
horschd schrieb:
müsste doch gehen, oder?
Nein, die Variable
n
wird in zwei Übersetzungseinheiten definiert. Du müsstest jetzt in den Headerextern int n; // nur Deklaration (Bekanntmachung)
schreiben und in eine der Implementierungsdateien
int n; // Definition (Speicheranforderung)
-
habs einfach mal ausprobiert:
test.hint n; int sec(void);
sec.c
#include <stdio.h> #include "test.h" int sec(void) { printf("sec n: [%d]\n", n); return 1; }
und first.c
#include <stdio.h> #include "test.h" int main(void) { n = 4711; printf("n: [%d].\n",n); sec(); return 1; }
und auf der bash dann
gcc first.c sec.c
tut klaglos ...
desktop:~/src$ ./a.out n: [4711]. sec n: [4711]
wieso kann der gcc das, so wie ich es auch intuitiv gemacht habe?
-
Ich hab grad aktuell ein ähnliches Problem, aber habs mit forward declaration gelöst!
-
Meine Lösung mit der forward declaration funktionierte bisher ganz gut, aber nun bin ich auf ein Problem gestoßen. Ich hab eine Modul.hpp und eine DatenModul.hpp, welche von einander abhängen! Ich kann sie nicht gegenseitig inkludieren deshalb hab ich in der Modul.hpp eine forward declaration gemacht:
#ifndef Modul_hpp #define Modul_hpp class DatenModul; class Modul { public: ...
In der DatenModul.hpp inkludiere ich dann Modul.hpp. Von der Modul.hpp werden alle möglichen Arten von Modulen abgeleitet (KameraModul, SensorModul, usw.) Die Modul.hpp hat deshalb ein private DatenModul* D; Sodass jedes Modul immer Zugriff aufs DatenModul hat. Im Konstruktor DER ABGELEITETEN MODULE wird D* das DatenModul zugewiesen (geht ja nur bei Erstellung der Module in der main).
Soweit so gut. Funktioniert wunderbar. Nur jetzt muss ich auch von der Modul.cpp auf D* zugreifen, genauer gesagt auf eine Methode von D* (also vom DatenModul). Und da ist ja nur eine forward declaration forhanden, das heißt er kennt diese Methode zu diesem Zeitpunkt noch gar nicht?
-
Um nochmal auf die ursprüngliche Frage zurückzukommen, Funktionen explizit als extern zu deklarieren kann unter Umständen beeinflussen, was der Compiler nachher in die Symboltabellen schreibt. Zum Beispiel schreibt der gcc mit -fvisibility=hidden explizit als extern deklarierte Funktionen nach wie vor mit Default-Sichtbarkeit ins ELF-Objekt. Naja, jedenfalls sofern ihm das nicht per Pragma mit Gewalt ausgeredet wird.
fabske: Eigentlich gehört das langsam in einen eigenen Thread und ins C++-Forum, aber du bindest halt in der Modul.cpp die DatenModul.hpp ein.
-
seldon schrieb:
fabske: Eigentlich gehört das langsam in einen eigenen Thread und ins C++-Forum, aber du bindest halt in der Modul.cpp die DatenModul.hpp ein.
Ahh! Richtig, das hat funktioniert! Danke