Konstante global definieren

Gast #177447
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.
Gast #177449
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.
Gast #177450
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.
Gast #177452
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
Gast #177453
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.
Gast #177454
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?
Gast #177455
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 /

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren