www.mikrocontroller.net

Forum: Compiler & IDEs Problem mit globaler Variable


Autor: Günther Frings (taraquedo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe gerade versucht meine globalen Variablen in eine cmd.h 
auszulagern. Es geht z.B. um eine Variable vom Typ uint8_t mit der 
Bezeichnung who. Diese wird außerdem in cmd.c von einer Funktion, sagen 
wir be_my_admin(), verändert.

Jetzt habe ich eben schmerzlich erfahren, dass wenn man static in cmd.h 
benutzt die Variable wohl irgendwie zweimal existiert und jede Änderung 
nicht in main.c ankommt. Also habe ich static weggelassen und jetzt 
dreht mir der Compiler durch! Er sagt mir ich hätte who mehrmals 
definiert. Laut Suchfunktion habe ich aber in allen Datei nur ein 
einziges Mal who in Verbindung mit uint8_t geschrieben. Außerdem kommt 
diese Fehlermeldung nicht wie üblich unter "Build" mit rotem Punkt zum 
Vorschein, sondern erst "Message", dass es PRobleme mit der elf-Datei 
gibt.

cmd.o:(.data+0x4): multiple definition of `who'
main.o:(.data+0x0): first defined here

Irgendwas trotteliges steckt im Code drin, denn ich habe versucht den 
Fehler "im kleinen" zu reproduzieren und da lief es. Also so habe ich es 
versucht nachzustellen, aber wie gesagt - das funktioniert so:
// --- main.c ----------------------------
#include "cmd.h"
extern uint8_t who; // mit oder ohne diese Zeile spielt keine Rolle

int main(void)
{
   who = 0;
   be_my_admin();
   return 0;
}
// --- cmd.h -----------------------------
#ifndef CMD_H
#define CMD_H

#include <stdint.h>

#define UID_ADMIN 0xFF

uint8_t who;

void be_my_admin(void);

#endif
// --- cmd.c -----------------------------
#include "cmd.h"

void be_my_admin(void)
{
   who = UID_ADMIN;
   return;
}

Fällt irgendjemanden spontan ein, wo ich suchen muss? Dieser Fehler 
nervt mich ganz besonders, weil vor dem Umpacken alles so schön 
funktionierte.

Grüße!

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du vertauscht Definition und Deklaration.

In die Headerdatei gehört

  extern uint8_t who;

In genau EIN Sourcefile gehört

  uint8_t who.

Autor: Günther Frings (taraquedo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahhh vielen Dank! Da habe ich genau falsch herum gedacht. Dann ist das 
mit dem extern also auch wieder so eine Sache dem Compiler so lange 
ruhig zu stellen und zu sagen "die Variable gibt es irgendwo, die 
Adresse wird dir der Linker sagen". Das macht natürlich alles viel mehr 
Sinn.

Interessanterweise hatte ich jetzt noch gerade herausgefunden, dass 
dieses o.g. Problem nur dann auftritt, wenn ich in cmd.h die Variable 
initialisiere. Sagen wir uint8_t who = UID_NOBODY; schreibe. Ohne, so 
wie oben, funktionierte es. Klar, weil ich im "Miniprogramm" den Header 
nur einmal in main.c eingebunden habe. Aber auch im Miniprogramm läuft 
es dann nicht mehr mit Initialisierung. Das wäre spannend zu wissen, was 
hier der Compiler für einen Unterschied macht.

Aber das Problem konnte ich lösen, vielen Dank!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Günther Frings wrote:
> Interessanterweise hatte ich jetzt noch gerade herausgefunden, dass
> dieses o.g. Problem nur dann auftritt, wenn ich in cmd.h die Variable
> initialisiere. Sagen wir uint8_t who = UID_NOBODY; schreibe. Ohne, so
> wie oben, funktionierte es.

Das Problem ist, dass in C eine Initialisierung immer mit
einer Definition verbunden ist. In dem Moment, wo eine
Initialisierung vorhanden ist, wird das als Definition aufgefasst,
unabhängig davon, ob ein extern davor steht.

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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