Konstanten mehrfach verwenden
-
compiler fehler wäre folgendes wenn konst definition in header steht:
fatal error LNK 1169: one or more multiply defined symbols found
-
Du hast in jeder Übersetzungseinheit eine eigene Version dieser Konstanten - und da muß der Linker dann herausfinden, welche nun tatsächlich verwendet werden soll. Um dem Linker zu helfen, hast du zwei Möglichkeiten - entweder du deklarierst die konstante als static (dann wird sie nicht mehr an den Linker übergeben) oder als extern (dabei brauchst du dann eine zentral gelegene Definition).
PS: sfds
-
wie würde dann die lösung für static oder extern in diesem fall aussehen?
würde in meiner oberen lösung 2x die konstante angelegt werden?
-
ok static ist easy. dann reicht es wenn die konstante im header steht, aber extern?
aber legt static nicht auch jeweils dann 2 konstanten an?
odrer darf man generell keine konstanten in header schreiben?
-
static:
//testcons.h static const char testcons[]="test";
extern:
//testcons.h extern const char testcons[]; //testcons.c const char testcons[]="test";
(ersteres legt in jeder ÜE eine Kopie an, letzteres verwendet eine Version der Konstanten im gesamten Programm)
PS: Um konstante Zeichenketten zu verwenden, muß man nicht unbedingt ein eigenes Array bereitstellen - da reicht auch ein Zeiger auf ein String-Literal
-
//testcons.h const char testcons[]; //testcons.c const char testcons[]="test";
...funktioniert komischerweise auch, aber macht wahrscheinlich das gleiche wie die einbindung mit static, oder?
aber sinnvoll ist doch nur die einbindung über extern, lieg ich da richtig?
-
Meinst du so als String-Literal?:
const testconst = L"test";
Was ist der Vorteil? kann ich dann auch jedes Feld des Strings ansprechen: z.B. a = testconst[2] ?
-
Rio1 schrieb:
Meinst du so als String-Literal:
const testconst = L"test";
Nein, das wäre nichtmal legaler C-Code. Ich meinte:
const char* testconst = "test";
Was ist der Vorteil? kann ich dann auch jedes Feld des Strings ansprechen: z.B. a = testconst[2] ?
Der Vorteil ist, daß der Compiler selber entscheiden kann, wie er String-Literale im Speicher unterbringt - und damit womöglich effektiver ist als wenn er jedes in ein eigenes Array packen müsste.
(und ja, über den Zeiger kommst du genausogut an deine Zeichen wie mit dem Array)
-
also gibts nen unterschied zwischen char ..[] und char * ..
wusst ich noch gar nicht.danke für deine vielen Tipps.
-
Rio_1 schrieb:
also gibts nen unterschied zwischen char ..[] und char * ..
wusst ich noch gar nicht.Ja, gibt's - den sieht man ja sogar im Quelltext
(oder sehen die eckigen Klammern für dich aus wie Sternchen?)
-
nö sehn aus wie eckige Klammern :p
mhh... also Fazit: die einbindung sollte bei Konstanten generell über das Schlüsselwort "extern" erfolgen?
-
also ich hab das ganze mal mittels SDCC Compiler getestet - mhh...
da ging die variante nur so://testcons.h extern const char testcons[5];
//testcons.c const char testcons[5]="test";
//main.c #include "main.h" #include "testcons.c" // ich konnte das ganz nur hier mit // einbindung des c files kompilieren, // einbindung des headers gibt einen LINK Fehler #include "bank.h"
//bank.c #include "bank.h" #include "testcons.h"
Ist das normal das ich in main.c die testcons.c einbinden muss, und die einbindung von testcons.h nicht funktioniert?
-
Normal nicht - .C Files sollte man nicht includen. Und eigentlich sollte auch die Implementationsdatei ihren eigenen Header einbinden, damit sie von den selben Voraussetzungen ausgehen kann wie die Anwendungsprogramme (auf deutsch: setz' mal ein
#include "testcons.h"
in die 'testcons.c').Btw bin ich mir nicht sicher, ob const-Werte external oder internal Linkage bekommen.
-
Und eigentlich sollte auch die Implementationsdatei ihren eigenen Header einbinden, damit sie von den selben Voraussetzungen ausgehen kann wie die Anwendungsprogramme (auf deutsch: setz' mal ein #include "testcons.h" in die 'testcons.c').
sorry, der header ist included.. hat ich bloß vergessen hinzuschreiben. Aber wie gesagt, dass ist SDCC. Keine Ahnung ob das was anders läuft. Hat mich auch gewundert. Auf jedenfall krieg ich beim einbinden des headers in main.c ein Link error...
-
// constants.h // constants.c ist hier nicht erforderlich. #ifndef _CONSTANTS_H_ // Mehrfaches Einbinden der Headerdatei verhindern #define _CONSTANTS_H_ // Deklaration und Definition in einem Rutsch. float PI = 3.14; #endif // _CONSTANTS_H_
// test1.h #ifndef _TEST1_H_ // Mehrfaches Einbinden der Headerdatei verhindern #define _TEST1_H_ float some_func(); // Deklaration der Funktion some_func() #endif // _TEST1_H_
// test1.c #include "test1.h" extern float PI; // Sagt dem Compiler Bescheid, das PI schon irgendwo definiert ist float some_func() // Definition der Funktion some_func() { return 3*PI; // Nur mal so, um etwas auszugeben }
Und nun endlich, last but not least, das Hauptprogramm:
// main.c #include <stdio.h> #include "constants.h" #include "test1.h" extern float PI; // Bescheid int main() { float fl = PI; printf("PI: %f\n", PI ); printf("some_func(): %f\n", some_func()); return 0; }
-
// test1.h #ifndef _TEST1_H_ // Mehrfaches Einbinden der Headerdatei verhindern #define _TEST1_H_ ... #endif // _TEST1_H_
auch das ist längst geschehn... ich hatte das nur nicht nochmal erwähnt...
daran liegt es nicht. Wie gesagt, für den Windows rechner funzt es, für SSDC nicht.ich würde konstanten im header durch extern ankündigen und im C file definieren! oder irre ich mich??? Du machst das doch gerade andersrum... und es sind auch keine Konstanten wie ich sehe..
-
Rio1 schrieb:
auch das ist längst geschehn... ich hatte das nur nicht nochmal erwähnt...
daran liegt es nicht. Wie gesagt, für den Windows rechner funzt es, für SSDC nicht.Wie lautet denn die Fehlermeldung ?
Rio1 schrieb:
ich würde die konstante im header durch extern ankündigen und im C file definieren. oder irre ich mich?? Du machst das doch gerade andersrum...
Ich habe auf ein C file verzichtet und die Variable, bzw. die Konstante gleich in der Headerdatei definiert. Ja, klar kannst du das auch in eine Header- und eine C-Datei aufteilen.
-
irgendein SDCC linker error.. das müsst ich zu hause raussuchen..kann ich nur in 1 woche posten...
-
Rio1 schrieb:
irgendein SDCC linker error.. das müsst ich zu hause raussuchen..kann ich nur in 1 woche posten...
Bei Linker-Fehlern fallen mir eigentlich nur zwei Varianten ein - Symbol nicht gefunden (d.h. du hast vergessen, die "testcons.c" mitzucompilieren und -linken) oder mehrfache Definition (das tritt idR dann auf, wenn der Name im Header definiert wurde (und dieser Header in mehreren Übersetzungseinheiten verwendet wird)).