Forum: PC-Programmierung wann und wofür extern verwenden?


von jan (Gast)


Lesenswert?

hallo,
wann muss eine funktion als extern deklariert werden?
Ich habe eine Funktion und variable, die ich in mehreren files benutzen 
möchte.

file1.h
1
uint8_t variable;
2
void function(void);


file1.c
1
#include "file1.h"

file2.c
1
#include "file1.h"


in file1.c und file2.c kann ich doch jetzt eigentlich variable und 
function benutzen oder nicht?
habe gehört, dass man dan eigentlicht ein extern davor schreibt. Aber 
was soll das genau bringen?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

jan schrieb:
> wann muss eine funktion als extern deklariert werden?

Nie, sie ist es implizit.

Was aber als extern deklariert werden muss, ist Deine Variable in der 
Headerdatei.

In Deinem Beispiel definierst Du die Variable in der Headerdatei, 
damit wird bei jedem Einbinden eine Kopie davon angelegt, was beim 
Linken des Programmes zu einer Fehlermeldung (mehrfach definiertes 
Symbol) führt.

In die Headerdatei gehört nur eine extern -Deklaration, aber in eine 
der *.c-Dateien die Definition.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rufus Τ. F. schrieb:
> Was aber als extern deklariert werden muss, ist Deine Variable in der
> Headerdatei.

Kommt drauf an, wie die Tools eine tentative Definition genau umsetzen, 
bei GCC z.B. abhängig von -f[no-}common wie hier erklärt:

Beitrag "Re: Wie verarbeitet der GCC die Speicherklasse extern?"

> In Deinem Beispiel definierst Du die Variable in der Headerdatei,
> damit wird bei jedem Einbinden eine Kopie davon angelegt, was beim
> Linken des Programmes zu einer Fehlermeldung (mehrfach definiertes
> Symbol) führt.

Außer das Ding landet in .comm und es gibt keine (non-tentative) 
Definion.

> In die Headerdatei gehört nur eine extern -Deklaration, aber in eine
> der *.c-Dateien die Definition.

ACK.

von zitter_ned_aso (Gast)


Lesenswert?

jan schrieb:
> file1.h
>uint8_t variable;
> void function(void);

außerdem fehlt da die passende include-Datei für uint8_t.

von jan (Gast)


Lesenswert?

Was ist denn dann für Funktionen besser geeignet? Also wenn ich ei e 
Funktion in mehreren c Dateien benutzen möchte habe ich ja jetzt zwei 
Möglichkeiten.
Annahme, ich habe zwei c Dateien.

File1.h
1
 void function(void)

File1.c
1
 #include "File1.h"

File2.c
1
 #include "File1.h"

Oder
File1.h
1
 void function(void)

File1.c
1
 #include "File1.h"

File2.h
1
 extern void function(void)

File2.c
1
 #include "File2.h"

Also entweder ich includiere eine fremde Header, oder erstelle eine 
eigene Header und benutze extern.

Wie macht man es denn normalerweise?
Ich würde eigentlich zweiteres vermuten. In der ersten Header könnten ja 
auch noch andere Funktionen sein, die in der zweiten c file nicht 
benutzt werden sollen. Aber si her bin ich mir da nicht.
Was wären dur die beiden Möglichkeiten andere vor oder Nachteile?

von Dirk B. (dirkb2)


Lesenswert?

in file1.h kommen alle Informationen (Deklarationen, typedefs, enums, 
...) die file2.c braucht, um die Funktionen aus file1.c benutzen zu 
können.

Mehr nicht.

von Dirk B. (dirkb2)


Lesenswert?

Zu Fall 2:
Das extern bei der Deklaration vin Funktionen ist implizit. Man muss es 
nicht hinschreiben.

Daher sind die Angaben identisch.

Wenn sich in file1.h etwas ändert, musst du es auch in file2.h ändern.

Zudem kann auch ein anderer Autor für file1 zuständig sein.

Das ist also der falsche Weg.

Das Prinzip mit den Header-Dateien wurde eingeführt, damit man nicht 
selber die ganzen Deklarationen nochmal schreiben muss.

von jan (Gast)


Lesenswert?

Aber wenn ich jetzt in file2.c file1.h includiere, dann habe ich ja alle 
Funktionen zur Verfügung, die in file1.h stehen (in meinem Beispiel ist 
es nur eine).
aber mal angenommen in file1.h wären mehrere Funktionen und nicht alle 
werden in file2.c benötigt. includire ich dann Trotzdem file1.h?

von Rolf M. (rmagnus)


Lesenswert?

jan schrieb:
> Also entweder ich includiere eine fremde Header, oder erstelle eine
> eigene Header und benutze extern.
>
> Wie macht man es denn normalerweise?
> Ich würde eigentlich zweiteres vermuten.

Nein, das erste. Genau dafür sind Header ja da - als Interface, in dem 
alles steht, was von außen nutzbar sein soll.

jan schrieb:
> Aber wenn ich jetzt in file2.c file1.h includiere, dann habe ich ja alle
> Funktionen zur Verfügung, die in file1.h stehen (in meinem Beispiel ist
> es nur eine).

Ja, und? Daraus resultiert ja kein Zwang, sie aufzurufen. in stdio.h 
sind auch sämtliche Funktionen, Makros und Typen, die zur 
Standard-I/O-Funktionalität gehören. Wenn ich davon nur printf verwende, 
geht die Welt nicht unter.

> aber mal angenommen in file1.h wären mehrere Funktionen und nicht alle
> werden in file2.c benötigt. includire ich dann Trotzdem file1.h?

Ja. Stell dir mal das andere Extrem vor: In file1.c sind 100 Funktionen 
definiert, von denen du 30 in file2.c, 50 in file3.c und 70 in file4.c 
benötigst. Würdest du dann in diesen drei Dateien all diese 
Funktionsdeklarationen nochmal explizit hinschreiben, nur weil in keinem 
davon alle 100 Funktionen genutzt werden?

: Bearbeitet durch User
von jan (Gast)


Lesenswert?

Rolf M. schrieb:
> Ja. Stell dir mal das andere Extrem vor: In file1.c sind 100 Funktionen
> definiert, von denen du 30 in file2.c, 50 in file3.c und 70 in file4.c
> benötigst. Würdest du dann in diesen drei Dateien all diese
> Funktionsdeklarationen nochmal explizit hinschreiben, nur weil in keinem
> davon alle 100 Funktionen genutzt werden?

touche.
Da hast du natürlich recht.

Danke dir nochmal für deine ausführliche Erklärung

von Dirk B. (dirkb2)


Lesenswert?

Eine Deklaration ist (nur) eine Information für den Compiler.

Da wird noch kein Speicher verbraucht.

von Dohanna (Gast)


Lesenswert?

"Extern" besagt, dass es sich lediglich um eine Deklaration handelt 
(belegt keinen Speicher), aber irgendwo muss die Variable / Funktion 
dann  auch definiert werden (belegt Speicher) damit sie nutzbar wird, 
das geschieht in diesem Zusammenhang in einer anderen Datei deiner Wahl, 
vergiss aber nicht die Datei zu inkludieren in der die Deklaration 
steht.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dohanna schrieb:
> "Extern" besagt, dass es sich lediglich um eine Deklaration handelt

Das ist bei Funktionsprototypen implizit der Fall, da kann man "extern" 
daher weglassen.

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.