Hallo Leute, wie der Titel schon sagt, habe ich ein Problem mit doppelten Definitionen. Ich habe eine Header-Datei, in der ich viele Konstanten definiere und zwei .c Dateien, in denen ich auf diese Konstanten zugreifen möchte. In den einzelnen Funktionen (die sich in den .c befinden) deklariere ich diese Konstanten mit "extern", um sie zu verwenden. Dies funktioniert auch ganz gut, wenn ich nur eine .c habe, die diese Konstanten verwenden will. Wenn ich in einer zweiten .c genauso in funktionen diese Konstanten mit "extern" deklariere, dann gibt der Compiler mir einen Fehler aus (multiple definitions...), obwohl ich da ja nichts definiere... wenn ich die Funktionen aus der einen .c in die andere kopiere und die erste vom Compiliervorgang ausschließe, dann gibt es keine Probleme. Ist wohl irgendein Problem, das entsteht, wenn ich die Funktionen in zwei .c aufteile. Ich hoffe ich habe mich nicht zu oft wiederholt =) Hate jemand vielleicht eine Lösung für das Problem? Gruß, Yaro
Statt den Text lang und breit verbal zu skizzieren und dies dann ins Forum zu schreiben: Wäre der Text direkt nicht sinnvoller? Also der Code.
Hier der Text =) ist aber ein wenig länger....wollte das eigentlich ersparen =)
Du kannst "const" Daten zwar nicht verändern, aber ansonsten sind es normale Daten, die an exakt einer Stelle definiert werden dürfen (const int var = 1). Überall sonst dürfen sie nur deklariert werden (extern const int var). Also ins .h File: extern const int var; und in genau ein .c File: const int var = 1;
Alles klar, jetzt funktioniert das auch. Ich dachte fälschlicherweise, dass ich Konstanten auch in einer Header-Datei definieren kann. Vielen Dank für die schnelle Hilfe Gruß, Yaro
"const" Daten sind nicht vergleichbar mit lexikalischen Konstanten, sondern sind lediglich unveränderliche Daten.
Du kannst dir mit const in Headern "lexikalische" Konstanten bauen: Ich benutze teilweise static const float PI = 3.0f; anstatt #define PI 3.0f Bei Arrays willst du das allerdings eher nicht machen, weil dann tatsächlich jede Kompilationseinheit die den Header benutzt eine eigene Kopie der Arrays enthält.
A. K. schrieb:
> Das geht nur in C++, nicht in C.
Das geht auch in C, nur ist nicht garantiert, dass der Compiler die
Konstante nicht doch in einer Variablen hinterlegt. Normalerweise
hat er aber bei derart einfachen Konstanten und aktivierter Optimierung
keinen Grund dazu.
> Normalerweise hat er aber bei derart einfachen Konstanten > und aktivierter Optimierung keinen Grund dazu. Darauf verlasse ich mich dabei natürlich, dürfte bei einem anständigen Compiler auch keine so abwegige Annahme sein.
Jörg Wunsch schrieb: > Das geht auch in C, nur ist nicht garantiert, dass der Compiler die > Konstante nicht doch in einer Variablen hinterlegt. Er mag im Rahmen von Optimierung der Wert von "const" Variablen direkt einsetzen. Aber der Compiler sollte an jeder Stelle, an der nur lexikalische Konstanten zulässig sind, freundlich aber bestimmt darauf hinweisen, dass eine Variable, so konstant der Wert sein mag, hier nicht zulässig ist. Deshalb würde mich interessieren, welcher C Compiler so etwas ausserhalb einer Funktion akzeptiert:
1 | static const int N = 10; |
2 | int a[N]; |
oder innerhalb einer Funktion:
1 | switch { |
2 | case N: |
3 | ...
|
4 | }
|
Bartlis Satz lautete: <<Du kannst dir mit const in Headern "lexikalische" Konstanten bauen:>> und genau dem habe ich widersprochen. Es entsteht nicht das Äquivalent einer lexikalischen Konstanten, sondern nur eine besser optimierbare Variable. Bei C++ Compilern sieht die diesbezügliche Sprachdefinition anders aus.
OK, an diesen Unterschied hatte ich nicht gedacht, hast Recht.
Bartli schrieb: > Darauf verlasse ich mich dabei natürlich, dürfte bei einem anständigen > Compiler auch keine so abwegige Annahme sein. Bei hochentwickelten Compilern wie GCC hast du damit sicherlich Recht. Bei Compilern, die nur im Kontext von Mikrocontrollern verwendet werden, würde ich mich darauf nicht verlassen.
Naja...wenn der Compiler Käse ist, kannst du dich auf gar nichts mehr
verlassen. Bei uns hat einer mal eine Weile lang ziemlich doof geschaut
bis er gemerkt hat, dass sein Compiler bei
extern int foo[];
mit den komischen Klammern nichts anfangen konnte und stillschweigend
extern int foo;
angenommen hat. Eben ein Compiler der nur im Kontext von Mikros
verwendet wird, bzw. besser gar nicht: aq430.
Spass beiseite, ich seh schon dass es da zwischen "funktioniert
grundsätzlich" und "optimiert gut" Unterschiede gibt.
Ansonsten:
> OK, an diesen Unterschied hatte ich nicht gedacht, hast Recht.
Ich auch nicht, habs heutzutage meistens mit C++ zu tun.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.