Forum: Compiler & IDEs Konstante global definieren


von Henning (Gast)


Lesenswert?

wie kann ich eine Konstante Global definieren, die in mehreren
Quelldateien verwendet wird?

Follgendes Problem: ich habe ein Projekt, das vorher aus einer
Quelldatei (main.c) bestand, in der alle anderen Sourcedateien per
#include hineingezogen wurden. In der makefile war auch nur SCR=main.c
definiert.
Damit ich aber in allen Dateien simulieren kann sollen alle
Quelldateien in der makefile angegeben werden. Mittlerweile habe ich
das auch geschaft, auch die #includes gelöst, und könnte kompilieren.
Das Problem steht aber noch bei 5 Konstanten. Definiere ich sie in der
Projekt-Header Datei (per include in allenQuelldateien) mäkelt der
linker die mehrfachen definitionen.
Makrodefinition wie #ifndef funktionieren scheinbar nich.
Definiere ich die Konstanten nur in der main.c fehlt sie in den anderen
Dateien komplett.

Wie kann man das umgehen, wie wird das richtig gelöst?
Es gibt zur Include-Story zwar viele Informationen, aber ich habe
leider niemanden gefunden der mein Problem hatte, bzw. was mir hilft.

von Dirk (Gast)


Lesenswert?

Ich glaube das geht so:

extern unsigned char variable;

Einfach mal ausprobieren!
Dirk.

von Jim (Gast)


Lesenswert?

Er wollte eine Konstante definieren, keine Variable. Die belegt
ausserdem Speicher.

Mit #ifdef geht das sehr wohl.
Am besten inkludierst Du die Header-Datei, in der Deine Konstanten
stehen, von allen Dateien und fragst per #ifdef ab, ob die Header-Datei
schon inkludiert wurde. So macht man das immer.

von Henning (Gast)


Lesenswert?

kannst du mir ein beispiel geben? ich habe schon ne menge ausprobiert,
aber die (für mich logischte) variante:

#ifndef incl
#include "netzwerk.h"
#endif

funktioniert nicht. in der netzwerk.h (meine headerdatei, die die
Definitionen und Konstanten für das Projekt enhält habe ich ausserdem

#define incl

eingefügt.

von Peter D. (peda)


Lesenswert?

Ist zwar etwas umständlich, funktioniert aber.
Schau Dir mal die standard Includes an, wie es dort gemacht wird.

Wenn aber erst der Linker meckert, dann sind es keine Konstanten,
sondern Funktionen oder Variablen.


Peter

von Joline (Gast)


Lesenswert?

@Henning:

>#ifndef incl
>#include "netzwerk.h"
>#endif

Ist schon fast richtig. Aber da beim nächsten Inkludieren das Flag
'incl' immer noch nicht definiert ist, wird der Kompiler
"netzwerk.h" wieder inkludieren. Also mußt Du 'incl' beim ersten
Mal definieren.

Das geht dann so:

#ifndef incl
#define incl
#include "netzwerk.h"
#endif

Am besten benennst Du das Flag auch noch passend, also z.B.
NETZWERK_H_INCL (oder so).
Wie Peter schon geschrieben hat, schau Dir mal die standard Includes
an.

Joline

von Henning (Gast)


Lesenswert?

ich habe weiter probiert, aber das kompilieren klappt immernoch nicht
bis zum ende fehlerfrei.

die Fehler tauchen erst beim Linker auf, er bemängelt alle Dateien, bei
denen das netzwerk.h includiert ist. Die Fehlermeldungen lauten
--
device.o(.bss+0x0): In function `WriteRTL':
d:\elektronik\avr\projekte\netzwerk/device.c:31: multiple
definition of `TCP_Socket_Status'
main.o(.bss+0x0):d:\elektronik\avr\projekte\netzwerk/main.c:78:
first defined here
--
wobei die Zeilenangabe leider müll ist, es sind zwar unterscheidliche
zeilennummern gemeldet, die haben aber nichts mit dem Problem zu tuen
(wie mir scheint). Die Zeilen die den linker wohl wirklich stören
sind:
-- (aus netzwerk.h)
const int mymac[6] = {0x00,0x20,0x18,0xb1,0x04,0xa2};
const int MYIP[4]  = {192,168,2,99};
unsigned char Sendpage = 2;
unsigned int TCP_Socket_Store[10]  = {0,0,0,0,0,0,0,0,0,0};
unsigned int TCP_Socket_Status[10] = {0,0,0,0,0,0,0,0,0,0};
--
mit 2 anderen zeile hat er kein Problem:
--
unsigned long Seq_counter;
unsigned long Ack_counter;
--
auffällig ist, das ihm die Zeilen mit Zuweisung stören. Wenn es richtig
ist, das die Arrays automatisch auf 0 definiert sind kann man die
zuweisung ja entfernen -> schon gehen die beide Zeilen OK.

Das könnte ich ja nun bei allen Zeilen machen und in der init() die
werte manuell setzen. was allerdings optisch nicht das schönste ist.
Wie kann man das umgehen

Wenns nicht ander Art des Include liegen kann könnt ihr das
überspringen:
Nur um nicht aneinander vorbei zu reden: wenn ihr mit standard
includes zB stdio.h mein, die hab ich mal untersucht -> ich habe jetz
in der netzwerk.h ganz am anfang die #ifndef und #define Anweisung
eingefügt und ganz am Dateiende die #endif. bei allen anderen Dateien
wird die datei normal per #include eingefügt.

von Henning (Gast)


Lesenswert?

ich habe die manuelle Wertzuweisung mal ausprobiert und konnte nun
komplett compilieren, linken und was noch so dazugehört.

Aber programmtechnisch ist die Sache nicht schön... Hab ihr eine Idee?

von Christof Krüger (Gast)


Lesenswert?

Die Geschichte mit #ifndef etc. verhindert nur, dass bei einem
Kompiliervorgang eine Datei mehrfach included wird. Alle .c-Dateien
deines Projekts werden ja einzeln kompiliert, daher stört sich der
Compiler erstmal nicht daran. Da in jedem object file, was die
netzwerk.h included hat das Symbol "TCP_Socket_Store" exportiert ist,
hat der Linker was dagegen, da du damit eigentlich eine Variable meinst,
die jetzt aber in allen .c-Files vorhanden ist.

Die Lösung des Problems ist folgende: Du verschiebst die Zeilen in
eine .c-Datei, am besten dahin, wo soe funktionell am besten
hinpassen, also dahin, wo du deine Netzwerk-Funktionen auch hast. Somit
wird nach dem Kompilieren aller dateien das Symbol "TCP_Socket_Store"
nur in DIESER Datei exportiert. Damit aber alle anderen source-Files
wissen, dass es irgendwo da draussen eine Variable "TCP_Socket_Store"
gibt, musst du entweder in jeder .c-Datei einzeln "extern unsigned char
TCP_Socket_Store[10];" reinschreiben, oder (was eleganter ist) eben in
die netzwerk.h schreiben.

Jetzt hast du folgende Situation:

netzwerk.c: definiert die Variable

x.c \
y.c  > wissen durch das "extern", dass es die variable woanders gibt
z.c /

von Henning (Gast)


Lesenswert?

Ich habe die Variablen und Konstanten nun mit extern eingebungen.

@Christoph Krüger:
Danke, das ist genau der Tip gewesen, der mir gefehlt hat!

Danke auch an die anderen!

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.