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
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
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
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.
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
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
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).
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
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.
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
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
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.
Eine eigene Frage?
Dieser Thread ist über 23 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.