"extern" bei unterschiedlichen .c macht Probleme

OP #1396874
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
#1396916
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;
Gast #1397489
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.
Gast #1397653
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.
#1399280
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.
#1399295
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.
Gast #1399780
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.

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