Forum: Compiler & IDEs "extern" bei unterschiedlichen .c macht Probleme


von Yaro G. (yaro)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Yaro G. (yaro)


Angehängte Dateien:

Lesenswert?

Hier der Text =)
ist aber ein wenig länger....wollte das eigentlich ersparen =)

von (prx) A. K. (prx)


Lesenswert?

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;

von Yaro G. (yaro)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

"const" Daten sind nicht vergleichbar mit lexikalischen Konstanten, 
sondern sind lediglich unveränderliche Daten.

von Bartli (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

Das geht nur in C++, nicht in C.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Bartli (Gast)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

OK, an diesen Unterschied hatte ich nicht gedacht, hast Recht.

von (prx) A. K. (prx)


Lesenswert?

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.

von Bartli (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.