Funktion durch header includieren oder als extern declarieren

Gast #6148010
Lesenswert?

Hallo,

ich habe eine Frage zum folgendne sacherhalt (in c)

file1.h
void function1(void);

file1.c
void function1(void){...}

um die Funktion function1 in einer neuen datei (file2.c) zu benutzen, 
kann ich ja entweder in file2.c
#include file1.h
oder
extern void function1(void);

Wann sollte man eine header includieren oder funktionen als extern 
declarieren?
Gast #6148020
Lesenswert?

Mit allem menschlichen Respekt und Verlaub: Deine Rechtschreibung und 
Grammatik weist darauf hin, dass Du den Einzelheiten Deiner Sprache 
(Deutsch und C) zu wenig Aufmerksamkeit schenkst. Ich möchte Dir sehr 
empfehlen, dass zu ändern.

Deine Frage läuft darauf hinaus, ob eine Deklaration mit und ohne 
"extern" Schlüsselwort gleichwertig ist, was nicht der Fall ist.

Ob nun die eine dieser Formen in der H-Datei steht oder die andere Form, 
ist dabei völlig gleichgültig.

Details dazu stehen in einem guten C-Buch.
#6148038
Lesenswert?

Theor schrieb:
> Deine Frage läuft darauf hinaus, ob eine Deklaration mit und ohne
> "extern" Schlüsselwort gleichwertig ist, was nicht der Fall ist.

Bei Funktionen ist das gleichwertig.

Die Grundideee hinter der Deklaration in einem header-files ist, in 
einem File alles zusammenzufassen, um das c-File benutzen zu können. Bei 
nur einer Funktion ist das nicht unbedingt nötig, aber reale Progamme 
bestehen üblicherweise aus mehr als nur einer Funktion.

Oliver
Gast #6148055
Lesenswert?

Von Anfang an angewöhnen, den Code in .h und .c zu trennen. Überall 
dort, wo du diese Funktionen / Klassen benötigst importierst du einfach 
den Header.

Dieser liefert lediglich Informationen über die Struktur dieser 
Funktionen / Klassen (Definitionen) und erzeugt keinen eigenen Code.

Solltest du in diesem Header globale Variablen benötigen, dann mit 
extern definieren, z.B. extern int i; Diese wird anschließend in der .c 
deklariert int i = 0;

Dann weiß jede .c Datei, die deinen Header inkludiert, dass es irgendwo 
eine "int i" gibt.
Gast #6148062
Lesenswert?

Bei Funktionen ist das "extern" komplett überflüssig und wird vom 
Compiler ignoriert.

Funktionen in Headern zu deklarieren hat mehrere Vorteile:
- Man kann den Header von verschiedenen .c Dateien aus inkludieren, und 
kann dann automatisch alle darin vorhandenen Funktionen nutzen
- Man kann im Header direkt noch für die Funktion benötigte Dinge wie 
structs und typ-Aliase definieren
- Man kann und sollte in der .c -Datei mit der Definition immer den 
Header mit der Deklaration inkludieren. Sollte man eine Inkonsistenz 
zwischen Definition und Deklaration haben, gibt der Compiler dann einen 
Fehler. Ohne diese Inkludierung fällt ein solcher Fehler zunächst nicht 
auf - insbesondere auch dann nicht, wenn man Deklarationen in .c 
-Dateien kopiert - und man wundert sich dann später über kuriose 
Probleme.

Einfache Faustregel: Funktionsdeklarationen nie in .c -Dateien packen, 
außer die Funktion ist "static" und Aufrufe an die Funktion kommen in 
eben dieser .c-Datei vor der Definition. "extern" bei Funktionen nie 
verwenden, da sinnlos.
#6148235
Lesenswert?

Theor schrieb:
> Mit allem menschlichen Respekt und Verlaub: Deine Rechtschreibung und
> Grammatik weist darauf hin, dass Du den Einzelheiten Deiner Sprache
> (Deutsch und C) zu wenig Aufmerksamkeit schenkst. Ich möchte Dir sehr
> empfehlen, dass zu ändern.

/offtopic on, Klugscheissmodus on

Theor, empfehle ich dir auch. Besonders den Unterschied zwischen "das" 
und "dass" solltest du dir anschauen!
Gast #6148251
Lesenswert?

Naja. Gut. Ich habe daneben gehauen. Ein gutes "C Buch" hätte in Bezug 
auf extern nichts genutzt. Allerdings in Bezug auf die 
include-Anweisung.

Mir ist die Grammatik und Rechtschreibung so sehr ins Auge gefallen ... 
heftig. Von was ich mich manchmal beeindrucken lasse ... Lach.
Gast #6150991
Lesenswert?

Technisch gesehen : egal, wo es steht. Der Precompiler fügt den Inhalt 
der .h-Datei für den Compiler an Stelle des Includes ein.
Menschlich gesehen : Alles was mehrfach im Projekt vorhanden ist, kann 
früher oder später auseinanderlaufen und damit unterschiedlich sein. Das 
ist der Anfang von lustigen Fehlern. Also für Funktionen und Variablen 
in C genau eine Deklaration. Und die sollte für den Compiler bei der 
Definition sichtbar sein. Dann ist klar gestellt, welchen Typ eine 
Variable hat und welche Aufrufkonventionen eine Funktion. (Ok eins noch 
: leere Klammern hinter dem Funktionsnamen in der Funktionsdeklaration 
oder -definition sind extrapfui)
Wenn Du das beherzigen willst, stehen also Deklarationen entweder in der 
einzigen .c Datei, die diese Funktionen oder Variablen benutzt, oder in 
einer .h-Datei, die von allen .c-Dateien eingebunden wird, die sie 
benutzen oder definieren.
Gast #6152662
Lesenswert?

Programmierer schrieb:
> Bei Funktionen ist das "extern" komplett überflüssig und wird vom
> Compiler ignoriert.

Das ist seit gefühlten 100 Jahren bekannt.

Dennoch halte ich es für eine sinnvolle Sache, nicht nur Variablen, 
sondern auch Funktionen in Headerdateien mit 'extern' zu versehen.

Aus Gründen der Einheitlichkeit und Lesbarkeit - auch wenn die Compiler 
das nicht einfordern.

Das ist fast dasselbe wie bei Kommentaren: Auch Kommentare sind dem 
Compiler schnurz. Dennoch sind sie sinnvoll (oder sollten es sein).

W.S.
Gast #6152669
Lesenswert?

Und warum soll eine Funktionsdeklaration mit "extern" dran besser lesbar 
sein? Für falls man das Semikolon am Zeilenende überliest, vergessen hat 
dass man gerade einen Header vor sich hat und sich verzweifelt fragt, wo 
der Funktionskörper ist?

Wenn alle Superkräfte haben, hat keiner Superkräfte. Wenn alle 
Funktionsdeklarationen extern haben, ...

Kommentare sind auch nur sinnvoll wenn sie nicht-offensichtliche Dinge 
erläutern, wovon es in guten Programmen wenige geben sollte. Das extern 
erläutert auch nur nochmal dass da kein Funktionskörper ist - 
offensichtlich!
Gast #6153083
Lesenswert?

Programmierer schrieb:
> Und warum soll eine Funktionsdeklaration mit "extern" dran besser lesbar
> sein? Für falls man das Semikolon am Zeilenende überliest, vergessen hat
> dass man gerade einen Header vor sich hat und sich verzweifelt fragt, wo
> der Funktionskörper ist?

Zum einen ist der Lesefluss tatsächlich besser: Ich kann über lange 
listen von "extern" hinweglesen, wenn mich declarationen nicht 
interessieren.

Zum anderen ist es konsistent: extern für extern.

In etwa wie geschweifte Klammern bei Compound-Statements. Nicht nötig 
bei einer Zeile, aber konsistent mit allen anderen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren