mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Mezzo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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):
display.h

#include "u8g2/u8g2.h"

extern u8g2_t u8g2;

void initDisplay();


display.c

#include "display.h"

void initDisplay() {
  u8g2_Setup_ssd1309_128x64_noname0_f(&u8g2, U8G2_R2, u8x8_byte_4wire_sw_spi, u8x8_avr_gpio_and_delay);
  ...
}


main.c

#include "display.h"

u8g2_t u8g2;

void main() {
  initDisplay();
}

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

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Mezzo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: b.nutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: leo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.