Forum: PC-Programmierung Funktion durch header includieren oder als extern declarieren


von Pascal (Gast)


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?

von Theor (Gast)


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.

von Oliver S. (oliverso)


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

von Glutenfreier laktoseintoleranter Frutarier (Gast)


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.

von Programmierer (Gast)


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.

von Theor (Gast)


Lesenswert?

Ich muss mich korrigieren.

Das "extern" ist - abgesehen von GCC-spezifischen Sonderfällen - 
überflüssig.

Danke für die Hinweise.

von Oliver S. (oliverso)


Lesenswert?

Theor schrieb:
> abgesehen von GCC-spezifischen Sonderfällen -

Und die wären?

Oliver

von Theor (Gast)


Lesenswert?

Oliver S. schrieb:
> Theor schrieb:
>> abgesehen von GCC-spezifischen Sonderfällen -
>
> Und die wären?
>
> Oliver

"visibility" als Attribut oder Option.

von Helmut -. (dc3yc)


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!

von Theor (Gast)


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.

von Oliver S. (oliverso)


Lesenswert?

Theor schrieb:
> "visibility" als Attribut oder Option.

Geht es vielleicht etwas genauer?
Einen Verweis auf "extern inline" hätte ich ja noch verstanden, aber 
"visibility"?

Oliver

von Theor (Gast)


Lesenswert?

Oliver S. schrieb:
> Theor schrieb:
>> "visibility" als Attribut oder Option.
>
> Geht es vielleicht etwas genauer?
> Einen Verweis auf "extern inline" hätte ich ja noch verstanden, aber
> "visibility"?
>
> Oliver

https://gcc.gnu.org/wiki/Visibility

von Oliver S. (oliverso)


Lesenswert?

Oh mann, ist das so kompliziert?

Kannst du nicht einfach in einem Satz kurz darlegen, wo gcc (und nur 
der) in einem C-Programm unbedingt ein "extern" fordert, von  mir aus im 
Zusammnehang mit visibility?

Das Problem ist: Kannst du nicht...

Oliver

von Theor (Gast)


Lesenswert?

@ Oliver

Lies es oder lass es. Mir egal.

von Oliver S. (oliverso)


Lesenswert?

Ums dann kurz nochmals abschliessend zusammenzufassen:

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

In diesem Sinne...

Oliver

von fop (Gast)


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.

von A. S. (Gast)


Lesenswert?

Immer Header includen.

Manchmal geht es nicht anders und man hackt die Deklaration ins C-File. 
So wie man manchmal goto verwendet.

von W.S. (Gast)


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.

von Programmierer (Gast)


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!

von A. S. (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.