Forum: Compiler & IDEs Verständnisfrage - "extern"


von Mezzo (Gast)


Lesenswert?

Hallo Forum,

ich hätte mal eine Frage zur richtigen Verwendung von "extern".

Mein Szenario:

Ich habe eine main.c, in der ich ein Menü implementiert habe.
Desweiteren habe ich eine display.h / display.c, in der die 
Initialisierung eines GLCD stattfindet sowie diverse zusätzliche 
Display-Funktion implementiert sind.

Sowohl main.c als auch display.c benötigen Zugriff auf eine Referenz zu 
einer u8g2 (Grafik-LCD Library) Instanz.

Mein Code (minimiert):
1
display.h
2
3
#include "u8g2/u8g2.h"
4
5
extern u8g2_t u8g2;
6
7
void initDisplay();


1
display.c
2
3
#include "display.h"
4
5
void initDisplay() {
6
  u8g2_Setup_ssd1309_128x64_noname0_f(&u8g2, U8G2_R2, u8x8_byte_4wire_sw_spi, u8x8_avr_gpio_and_delay);
7
  ...
8
}


1
main.c
2
3
#include "display.h"
4
5
u8g2_t u8g2;
6
7
void main() {
8
  initDisplay();
9
}

Kann mir jemand sagen, ob die Verwendung von 'extern' so korrekt ist?
Das Programm wird fehlerfrei kompiliert, allerdings wird es das auch, 
wenn ich 'extern' in der main.c verwende anstatt in der display.h.

Wie herum ist es richtig?

Vielen Dank für eure Hilfe.

Mario

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Mezzo schrieb:
> Kann mir jemand sagen, ob die Verwendung von 'extern' so korrekt ist?

Ja.

Mezzo schrieb:
> Wie herum ist es richtig?

In diesem Fall funktionieren zwar beide, aber die erste Version ist 
sinnvoller. Wenn das "extern" in der main ist, und du die "display.h" 
irgendwann später von einer anderen Datei inkludierst, hast du eine 
doppelte Definition und bekommst Linker-Fehler.

Die Regel ist eigentlich ganz einfach:
Variablen die global überall sichtbar sein sollen einmal in einer 
Header-Datei mit "extern" deklarieren, und in genau einer .c-Datei 
einmal ohne "extern" definieren.

Globale Variablen sind aber allgemein nicht sehr sauber und können den 
Code schwer wartbar machen. Indem du "u8g2" als Parameter mit an 
"initDisplay" übergibst vermeidest du das komplett. Somit könntest du 
später auch relativ simpel mehrere Displays ansprechen.

Warum kommen zu "extern" eigentlich letztens so viele Fragen... So 
schwierig ist das ja auch nicht...

von Mezzo (Gast)


Lesenswert?

Hallo Niklas,

vielen Dank für Deine ausführliche Erklärung.
Ich werde den Code umbauen und die Referenz auf das Display beim Aufruf 
der Funktionen durchreichen. Das erscheint mir auch übersichtlicher, da 
man ja sonst auf den ersten Blick überhaupt nicht sieht, wo die Variable 
u8g2 noch verwendet wird...

Trotzdem gut zu wissen, wie man 'extern' hier richtig anwenden würde.

1000 Dank!

von b.nutzer (Gast)


Lesenswert?

"extern" heißt nur "wird woanders definiert".

Fun fact: Funktionen (bzw. Deklarationen solcher) sind standardmäßig 
"extern" und brauchen deshalb nicht explizit so deklariert zu werden.

von leo (Gast)


Lesenswert?

Mezzo schrieb:
> void initDisplay() {

Ist korrekt aber schlechter Stil. Definier dein Displayobject in main() 
und gib es an init als Parameter weiter. Je lokaler Die Variabeln umso 
uebersichtlicher.

leo

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.