mikrocontroller.net

Forum: Compiler & IDEs Header Files


Autor: Günter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

bin etwas durcheinander, warum es nicht klappt. Bei anderen Compilern 
funktioniert es so. Warum nicht beim AVRGCC?

Also, in meinem Main.C steht zu beginn:

#define MAIN_C
#include "main.h"

bla bla bla



in der Main.h



#ifdef MAIN_C
unsigned char
#else
extern unsigned char
#endif

sendepos=0,
 sendewort[6],
 empfangswort[6],
 maxbytes=0;




Ok, soweit. Wenn ich nun in einem anderen C-File #include "main.h" mache 
dann bekomm zuerst Warnungen bezüglich externer deklaration und dann bei 
Main.c  "Multiple definitions" angemeckert.

Sieht jemand den fehler?


Gruss Günter

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Günter,
mach das mal so in allen Deinen Headerfiles:

blabla.h :

#include "xxy.h"
#include "yyx.h"

#ifndef _INCLUDE_BLABLA
#define _INCLUDE_BLABLA

void xyz(void);

#endif

Grüße
Oliver

Autor: Oryx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Günter,

wie soll denn der arme Compiler externe Variablen initialisieren.

Die Definition von Variablen sollte nicht in einer H-Datei stattfinden.

Auch die Deklaration von Variablen in den H-Dateien ist nicht toll, da 
sie zur Verwendung von vielen global genutzten Varablen führt.

Schreibe lieber in jeder C-Datei, quasi als Strafe extern xxxx.

Vermeide bedingte Compilierung, vor allem, wenn sie sich vermeiden 
lässt.

Was auf anderen Compilern kompilierbar ist, muß nicht unbedingt richtig 
sein.


"main.c"
unsigned char sendepos=0;
unsigned char sendewort[6];
unsigned char empfangswort[6];
unsigned char maxbytes=0;


"andere_datei.c"
extern unsigned char sendepos;
extern unsigned char sendewort[6];
extern unsigned char empfangswort[6];
extern unsigned char maxbytes;

In einer von beiden eingelesenen H-Datei könnten nun noch die 
Arraylängen stehen, damit man bei einer Änderung nicht durch alle 
Dateien ackern muß.

Oryx

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bezeichner, die mit Unterstrichen beginnen, sind übrigens tabu.

Eine etwas elegantere Variante, dergestalt die Externdeklaration
unterzubringen, sieht ungefähr so aus:

foo.h:

#ifndef EXTERN
#define EXTERN extern
#endif

EXTERN int foo;
EXTERN char bar[xxx];

main.c:
#define EXTERN
#include "foo.h"

alleanderen.c.

#include "foo.h"

Oliver, ja, bei Funktionsdeklarationen darf man das extern
auch getrost weglassen, das ist implizit.  Bei Variablen ist
das etwas anders.

Übrigens, Günter, meine Kristallkugel ist gerade defekt,
eventuell schreibst Du ja nochmal, welche Warnungen Du
denn bekommst.

Autor: Günter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erst mal danke für die Hilfe, aber funktionieren tut es immer noch nicht 
mit der Variablen Deklaration in nem Header File.

Hab es mal genau so gemacht wie Joerg und habe im endeffekt die selben 
Compiler Warnungen und Fehler wie schon vorher.

Also, der Compiler kommt an ein "Untergeordnetes C -File".
Warnung des Compilers:
in file included from seriell.c:1:
main.h:11: warning: `maxbytes' intialized and declared `extern'

Beim linken kommt dann der Fehler: multipe definitions of maxbytes für 
die extern deklarierten Variablen.

Gruss Günter

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
blabla.h :
~~~~~~~~~~~

#ifndef _INCLUDE_BLABLA
#define _INCLUDE_BLABLA

// Externe Funktionsdeklaration
extern char blub;

// Prototyp der Funktion xyz
void xyz(void);
#endif


blabla.c
~~~~~~~~~

char blub;

void xyz(void)
{
...
}

so geht es 100%

Grüße
Oliver

Autor: Oryx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Günter,
Du machst es leider nicht so, wie es Jörg und Oliver beschreiben.

In Deiner H-Datei steht:
extern unsigned char maxbyte = 0;

Die Zuweisung muß weg!!!!
Schreibe:
extern unsigned char maxbyte;

Das ist alles.
Wo soll denn der Compiler/Linker Deinen Wert 0 hinschreiben????

Oryx

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
p.s.: Eine Zuweisung von 0 auf eine globale/statische Variable
ist immer pure Platzverschwendung.  Die Dinger sind per
definitionem (des C-Standards) auf 0 initialisiert.  Explizites
manuelles Initialisieren bringt nichts außer zusätzlichem
Verbrauch an Flash-ROM (für den expliziten initializer).

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

das kann ich zumindest für den aktuellen AVRGCC nicht bestätigen. Ich 
vermute mal der optimiert das weg (obwohl ich dir natürlich nicht 
widersprechen will, du bist ja in die Entwicklung des AVRGCC verstrickt)

Ich bekomme identische Flashgrößen ob ich die globalen Variablen 
explizit initialisiere oder nicht. Und wenn es am Flashverbrauch nichts 
ändert laß ich die Initialisierung liebr stehen. Rein aus Gründen der 
Lesbarkeit des Codes.

Matthias

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Recht, das scheint neu zu sein, hat er früher nicht
gemacht.

OK, dann nehme ich die Hälfte zurück :).  Die Initialisierung
mit 0 kostet zumindest nichts mehr.  Unsinnig ist sie trotzdem.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ich halt es nicht für unsinnig. Wenn jamend den Code zu lesen bekommt 
der nicht so mit dem C-Standard vertraut ist wie du wundert er sich das 
uninitialisierte Variablen verwendet werden bzw. das der Compiler nicht 
davor warnt. Ich halte es also für nicht ganz verkehrt die 
Initialisierung explizit hinzuschreiben.

Matthias

Autor: Günter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Hilfe...
Jetzt klappts. Lag nur an der Unsinnigen Zuweisung.
So kann es gehen wenn man mit so einigen Sprachen rumhantieren muß. Da 
vermischt sich manches leider.

Nochmals Danke für die Hilfe!

Günter

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias, wenn jemand den Code zu lesen bekommt und von der
Sprache keine Ahnung hat, dann sollte er wohl zuallererst die
Sprache lernen.  Ansonsten wird er sich über Konstrukte wie

a <<= 1;
a = b = c = 23;

u. ä. noch viel mehr wundern.

Wenn jemand vorgibt, C zu beherrschen, dann sollte er wiederum
auch wissen, daß globale und statische Variablen anders als in
anderen Sprachen eine Initialisierungsgarantie besitzen und man
sich darauf verlassen darf.

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.