Variablen extern in Header files?
-
Hallo,
ich arbeite in einem Projekt in dem alle Variablen in headern als extern deklariert werden. Warum machen die das?
Wenn ein C file diesen Header inkludiert, dann muss doch diese deklaration nicht extern sein oder?
Ich habe mal gelernt, dass man nur dann extern nimmt, wenn man ohne Header arbeitet und in einem C file die Variable global definiert und in einem anderen C file zu Beginn diese Variable extern deklariert. Nachdem man die Objekts der beiden C Files zusammenlinkt haben nun beide Dateien zugriff auf diese Variable.
Braucht man das extern in Header files wirklich?
-
Wie Du schon richtig erkannt hast, führt das dazu, dass diese Variablen in allen C-Dateien, die dieses Headerfile einbinden, zur Verfügung stehen.
Braucht man das?
Ist eine potentielle Fehlerquelle.
-
Die Variablen in den Headers sind schon ausgewählt. Nur stört mich, dass sie extern deklariert sind, da reicht doch eine normale deklaration ohne auch.
Wie ist das mit extern Deklarationen von Funktionen in Headern?
Ist das genauso unnötig wie für Variablen, oder hat das da schon einen tieferen Sinn?
-
Noob12345 schrieb:
Hallo,
ich arbeite in einem Projekt in dem alle Variablen in headern als extern deklariert werden. Warum machen die das?
Weil sie unsauber arbeiten und sich nur mit globalen Variablen, sogar programmweit globalen Variablen, behelfen können. Mein Beileid, das wird ein Horrorprojekt. Insbesondere, wenn man selber noch nicht so ganz fit in C ist.
Wenn ein C file diesen Header inkludiert, dann muss doch diese deklaration nicht extern sein oder?
Doch, natürlich. Wie willst du sonst eine Variable deklarieren, ohne sie zu definieren? Eine Definition hätte definitiv nichts im Header verloren, weil man sonst schließlich mehrfache Definitionen hätte.
Ich habe mal gelernt, dass man nur dann extern nimmt, wenn man ohne Header arbeitet und in einem C file die Variable global definiert und in einem anderen C file zu Beginn diese Variable extern deklariert. Nachdem man die Objekts der beiden C Files zusammenlinkt haben nun beide Dateien zugriff auf diese Variable.
Ein Headerinclude ist eine reine Textersetzung. Das was du gerade beschreibst ist der zustand, nachdem der Header eingesetzt wurde. Also genau das was man möchte. Wenn du jedoch gelernt hast, dass das was mit Headern und Nicht-Headern zu tun hätte, dann war das ein schlechter Lehrer und du solltest mit Vorsicht genießen, was du sonst noch so gelernt hast.
Braucht man das extern in Header files wirklich?
Man kann sich immer Ausnahmefälle konstruieren, daher mag ich absolute Aussagen in der Programmierung nicht. Aber hier: Klares Ja!
Aber nochmal: Allein schon die Beschreibung lässt nichts gutes über die Codequalität ahnen. extern an sich braucht man in absoluten Ausnahmefällen. Und du sagst, es wären alle Variablen extern
-
Stimmt du hast recht, ohne ein extern wäre das ja eine erneute Definition einer Varibale für jedes C File welches diesen Header inkludiert?
Also muss sie extern deklariert werden! Ziemliche verwirrung.Was das Horrorprojekt angeht, manche Projekte erfordern viele globale Variablen um sie z.B. messbar und verstellbar zu machen.
Falls du das als Horror ansiehst, solltest du für dich in kein Fahrzeug mehr einsteigen, denn da wird sehr sehr oft global gearbeitet, auch wenn das sehr gefährlich ist.SeppJ schrieb:
Noob12345 schrieb:
Hallo,
ich arbeite in einem Projekt in dem alle Variablen in headern als extern deklariert werden. Warum machen die das?
Weil sie unsauber arbeiten und sich nur mit globalen Variablen, sogar programmweit globalen Variablen, behelfen können. Mein Beileid, das wird ein Horrorprojekt. Insbesondere, wenn man selber noch nicht so ganz fit in C ist.
Wenn ein C file diesen Header inkludiert, dann muss doch diese deklaration nicht extern sein oder?
Doch, natürlich. Wie willst du sonst eine Variable deklarieren, ohne sie zu definieren? Eine Definition hätte definitiv nichts im Header verloren, weil man sonst schließlich mehrfache Definitionen hätte.
Ich habe mal gelernt, dass man nur dann extern nimmt, wenn man ohne Header arbeitet und in einem C file die Variable global definiert und in einem anderen C file zu Beginn diese Variable extern deklariert. Nachdem man die Objekts der beiden C Files zusammenlinkt haben nun beide Dateien zugriff auf diese Variable.
Ein Headerinclude ist eine reine Textersetzung. Das was du gerade beschreibst ist der zustand, nachdem der Header eingesetzt wurde. Also genau das was man möchte. Wenn du jedoch gelernt hast, dass das was mit Headern und Nicht-Headern zu tun hätte, dann war das ein schlechter Lehrer und du solltest mit Vorsicht genießen, was du sonst noch so gelernt hast.
Braucht man das extern in Header files wirklich?
Man kann sich immer Ausnahmefälle konstruieren, daher mag ich absolute Aussagen in der Programmierung nicht. Aber hier: Klares Ja!
Aber nochmal: Allein schon die Beschreibung lässt nichts gutes über die Codequalität ahnen. extern an sich braucht man in absoluten Ausnahmefällen. Und du sagst, es wären alle Variablen extern
-
Aber wo ich Recht habe sind Funktionen.
Diese müssen in Headern doch nicht extern deklariert werden, da habe ich doch Recht oder?
also im Header ist doch beides gleich?
extern void foo(void);
void foo(void);
-
Noob12345 schrieb:
ohne ein extern wäre das ja eine erneute Definition einer Varibale für jedes C File welches diesen Header inkludiert?
Ja.
Noob12345 schrieb:
Diese müssen in Headern doch nicht extern deklariert werden, da habe ich doch Recht oder?
extern
bei Funktionsdeklarationen ist schon implizit gegeben. Kann man dranschreiben, muss man aber nicht. Im Zweifelsfall verwirrt man damit bloß andere Programmierer, weil sie das noch nie gesehen haben und sich fragen, warum du dort einextern
gesetzt hast. Es ist ungefähr so sinnvoll wie einauto
vor Variablen mit automatischer Speicherklasse (außer dass man mitauto
einen C++-Programmierer noch viel mehr verwirren würde als mitextern
)also im Header ist doch beides gleich?
extern void foo(void);
void foo(void);Ja, das sind beides Deklarationen von Funktionen mit externer Bindung.
Lies mal ein Buch, über die genaue Bedeutung von extern und den Unterschied zwischen Deklaration und Definition.
Noob12345 schrieb:
Falls du das als Horror ansiehst, solltest du für dich in kein Fahrzeug mehr einsteigen, denn da wird sehr sehr oft global gearbeitet, auch wenn das sehr gefährlich ist.
Das macht es auch nicht besser. Hat der ADAC nicht festgestellt, dass die häufigste Pannenursache heutzutage Softwareprobleme sind?
-
Noob12345 schrieb:
Stimmt du hast recht, ohne ein extern wäre das ja eine erneute Definition einer Varibale für jedes C File welches diesen Header inkludiert?
Richtig erkannt, der Compiler würde sich bei einer erneuten Definition mit dem gleichen Namen im gleichen (hier globalen) Sichtbarkeitsbereich auch weigern.
Noob12345 schrieb:
Also muss sie extern deklariert werden! Ziemliche verwirrung.
Die Verwirrung liegt ausschließlich bei dir.
Du hast Deklaration und Definition noch nicht richtig verstanden und verinnerlicht, übrigens genauso wie die Entwickler deines Programms.
Der extern-Spezifizierer kennzeichnet eine ausschließliche Deklaration, d.h. niemals handelt es sich hier dann um eine Definition.
extern-Deklarationen für denselben Namen können beliebig oft vorkommen, Definitionen pro Name und Sichtbarkeitsbereich nur genau 1x.Noob12345 schrieb:
Was das Horrorprojekt angeht, manche Projekte erfordern viele globale Variablen um sie z.B. messbar und verstellbar zu machen.
Naiver Anfängerschrottglaube.
Die Verwendung/das Design von globalen Variablen deuten in den allermeisten (bei Anfängern in allen) Fällen auf o.g. naive C-Kenntnisse hin, daran ändert auch dein wiederum laienhafter Hinweis auf häufige Verwendung in praktischen und akademischen Umfeldern nichts.
Schaue dir mal die Probleme an, die durch solcherlei statisch/globale Verwendung von Speicherbereichen auftreten, die Standardbibliothek macht (zugegebenermaßen) auch sowas, z.B. strtok,errno,strerror,*time,tmpnam,... erfordern per se Extrabehandlung, Probleme die durch Autoren deiner dir bekannnten Programme extrabehandelt werden müssen (wenn sie es denn überhaupt machen) und das nicht nur in Multithreadumgebungen, Probleme die man bei Verzicht auf solcherlei "Design" getrost ignorieren und sich auf die fachlichen konzentrieren kann.
-
Noob12345 schrieb:
also im Header ist doch beides gleich?
extern void foo(void);
void foo(void);Eine Funktionsdeklaration/Prototyp ist wie gesagt schon per se eine Deklaration, ein zusätzlicher Deklarationsspezifizierer extern ist redundant.
Bei Variablen
extern int foo; int foo;
kann aber der Compiler nicht feststellen, ob es eine Deklaration oder eine Definition (mit impliziter) Deklaration sein soll, extern ist hier also zur Kennzeichnung notwendig.
Include-Dateien sind ausschließlich für solche ausschließlichen Deklarationen gedacht, was die anderweitige Verwendung durch Laien nicht ausschließt.
-
Warum ich überhaupt Frage hat folgenden Hintergrund:
Habe eine neue Funktion definiert und sie extern deklariert im header.
Anschließend wurde diese Funktion nie aufgerufen und ich hab viel Zeit verloren.
Nachdem ich einen Debugger angeschlossen habe, sehe ich im C Code den Aufruf, jedoch keinen Assembler call.So dann hab ich das extern weggelassen, neu compiliert und schon war der Assemblercall zu sehen.
Wahrscheinlich hat das ganze nichts mit extern zu tun gehabt, sondern ich hätte einfach ein make clean machen sollen, dennoch wurdert mich, dass der Debugger den C call gesehen hat, aber es keinen Assembler call gab.
-
Zeig mal Code. Deine Beschreibung ist zu wirr und deine bisherigen Beiträge haben gezeigt, dass du teilweise Begriffe durcheinander bringst. Allein deine Beschreibung reicht daher nicht um eine Vermutung anzustellen, was da passiert ist.
-
Noob12345 schrieb:
Warum ich überhaupt Frage hat folgenden Hintergrund:
Habe eine neue Funktion definiert und sie extern deklariert im header.
Anschließend wurde diese Funktion nie aufgerufen und ich hab viel Zeit verloren.
Nachdem ich einen Debugger angeschlossen habe, sehe ich im C Code den Aufruf, jedoch keinen Assembler call.So dann hab ich das extern weggelassen, neu compiliert und schon war der Assemblercall zu sehen.
Wahrscheinlich hat das ganze nichts mit extern zu tun gehabt, sondern ich hätte einfach ein make clean machen sollen, dennoch wurdert mich, dass der Debugger den C call gesehen hat, aber es keinen Assembler call gab.
wieso deklarierst du Funktionen als extern?
Außerdem, wenn du nach dem clean+make eh eine funktionsfähige Version hast, warum fragst du?Mal abgesehen davon: hatte auch mit solch einer C Software zu tun. Alles wurde über externe globale Variablen übergeben, nix da mit Übergabe als Funktionsparameter. Ich kann dir sagen, das ist die reinste Katastrophe. Sicher 50% der Zeit musste ich in Probleme investieren, die damit zusammenhängen.
In C kann man sich doch auch ein klein bisschen Mühe geben Daten gut zu strukturieren und das Programm zu modularisieren, dadurch lässt sich jedes Programm schöner gestalten, auch im Automotive Bereich (warum soll der Bereich eine Ausnahme darstellen?).
In einem Modul (also H + C File) sind einerseits Typdefinitionen, als auch Funktionen zu finden, die mit den definierten Typen zusammenarbeiten.
Du machst eine Struktur, die alle Daten, die zusammengehören, beinhaltet. Zum Beispiel struct Messung_s {int size; char* comment; int data;...}; Aus dieser Struktur machst du mit typedef einen Typ, z.B. messung_t.
Und genau für diesen Typen definierst du dann einen Satz von Funktionen, z.B. int analyse(messung_t m){...Analyse, Ergebnis ist ein int... return erg;}Ich sehe keinen Grund, warum dieser Ansatz nicht auch im Automotive Bereich funktioniert. Eigentlich findet man diesen Ansatz bei vielen bekannten Funktionen und Bibliotheken. Denke nur mal an die C-Datei Funktionen mit der Datenstruktur FILE* datei; sowie all die dazugehörenden Funktionen.
Ich will dir aber nicht zuviel Hoffnung machen: wenn 99% eines Programms so chaotisch sind, hat man fast keine Chance bei Erweiterungen dagegen anzukämpfen. Schließlich sollten sich die Erweiterungen möglichst gut ins Gesamtbild einfügen.
-
dfsdffd schrieb:
In C kann man sich doch auch ein klein bisschen Mühe geben Daten gut zu strukturieren und das Programm zu modularisieren, dadurch lässt sich jedes Programm schöner gestalten, auch im Automotive Bereich (warum soll der Bereich eine Ausnahme darstellen?).
Er stellt keine Ausnahme dar. Es *wird* doch modularisiert, und es wird sich auch extrem viel Mühe gegeben, das ganze zu strukturieren. Anders hat man über viele hundert oder tausend Signale auch keinen Überblick.
Was nicht bedeutet, dass die Variablen nicht global sein können. Aber wo ist das Problem -- sie repräsentieren ohnehin einen globalen Zustand, und sie müssen auch an einer festen Speicheradresse zu finden sein, damit man von außen darauf zugreifen kann. Oder wie meinst du läuft das mit dem Verstellen von Parametern und Kennlinien zur Laufzeit (sprich auf der Teststrecke)?
Eventuell kann Tim auch mal was dazu sagen.