Forum: Compiler & IDEs Header Files


von Günter (Gast)


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

von Oliver (Gast)


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

von Oryx (Gast)


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

von Joerg Wunsch (Gast)


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.

von Günter (Gast)


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

von Oliver (Gast)


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

von Oryx (Gast)


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

von Joerg Wunsch (Gast)


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).

von Matthias (Gast)


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

von Joerg Wunsch (Gast)


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.

von Matthias (Gast)


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

von Günter (Gast)


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

von Joerg Wunsch (Gast)


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.

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.