mikrocontroller.net

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


Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Yaro G. (yaro)
Datum:
Angehängte Dateien:

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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Yaro G. (yaro)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A. K. (prx)
Datum:

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

Autor: Bartli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht nur in C++, nicht in C.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bartli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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:
static const int N = 10;
int a[N];
oder innerhalb einer Funktion:
switch {
case N:
  ...
}

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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bartli (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.