Halo Leute ich will drei Dateien erstellen aber ich bekomme die
Fehlermeldung "undefined reference to 'foo'". Ich komme nicht dahinter
warum es nicht geht.
my.cpp
cpp schrieb:> Ich komme nicht dahinter> warum es nicht geht.
Wo ist "foo" denn definiert? Du hast mit "extern int foo;" nur eine
forward declaration gemacht, d.h. du sagst an dass in einer der .cpp
Dateien irgendwann eine Definition folgt. Wenn keine kommt, bekommst du
eben diese Fehlermeldung.
Meine Glaskugel meint, dass du sie wahrscheinlich als lokale Variable
definiert hast.
C kann man nicht nach trial-and-error lernen - bzw. ist es zumindest
extremst mühsam. Besorge dir ein vernünftiges Buch und gehe es Schritt
für Schritt durch.
Rolf M. schrieb:> C kann man nicht nach trial-and-error lernen - bzw. ist es zumindest> extremst mühsam.
Und man lernt es verkehrt, denn viele Dinge die zu "funktionieren"
scheinen sind tatsächlich falsch und gehen irgendwann schief.
Jörg W. schrieb:> Du musst sie natürlich auch global anlegen, nicht innerhalb von main().
Ja so funktioniert es aber was macht es für einen Sinn foo in my.h mit
extern zu deklarieren, dann in use.cpp nochmals mit "int foo;" anzulegen
und in main mit "foo=7" zu definieren?
Die Aufgabenstellung lautet, dass foo in main mit 7 initialisiert werden
soll.
olo schrieb:> Ja so funktioniert es aber was macht es für einen Sinn foo in my.h mit> extern zu deklarieren, dann in use.cpp nochmals mit "int foo;" anzulegen> und in main mit "foo=7" zu definieren?
Header files werden in vielen compilations units eingebunden. Man will
all diesen bekannt geben, dass eine globale Variable foo existiert und
welchen Typ diese hat. Dafür die Deklaration. Man will aber nur Speicher
für diese einmal anlegen, und diese nur einmal initialisieren, dafür die
definition. Definiert man etwas häufiger oder seltener als einmal hat
man einen fehler (ausser man nutzt weak symbols, aber diese sind eine
compiler extension und kein standard c++). Ein Vorteil dieser Aufteilung
ist, dass man jede compilation unit (die .cpp files) compilieren kann,
ohne die anderen zu benötigen. Lediglich die Header files welche das
Interface darstellen sind notwendig. Erst beim linken werden alle
Codeteile benötigt. Strengenommen könnte man zwar, wenn man shared
libraries benutzt, gegen diese Linken ohne diese oder deren Code zu
haben, wenn man deren Symbole kennt, indem man diese zur Runtime vom
program loader auflösen lässt, aber die meisten Compiler sehen dies
nicht vor.
olo schrieb:> und in main mit "foo=7" zu definieren?
Wenn du die Sprache offenbar lernen sollst, dann solltest du mit den
Begrifflichkeiten anfangen.
Die Deklaration ist das, was in my.h steht.
Die Definition ist "int foo;".
"foo = 7" ist eine Zuweisung.
> Die Aufgabenstellung
Du wirst es nicht schaffen, eine Programmiersprache durch trial&error
in einem Forum zu erlernen. Ein bisschen Grundlagen musst du dir
schon selbst aneignen.
Nicht vom hier geschilderten Problem unterscheidet sich zwischen C und
C++.
Die Grundlagen sind ziemlich lang die gleichen; es ist für jemanden, der
C++ wirklich verstehen will, durchaus sinnvoll, auch C zu verstehen.
In nur wenigen Bereichen verhält sich C-Code anders als als C++-Code
interpretierter C-Code.
Rufus Τ. F. schrieb:> Nicht vom hier geschilderten Problem unterscheidet sich zwischen C und> C++.
Das ist zwar korrekt, aber...
> Die Grundlagen sind ziemlich lang die gleichen; es ist für jemanden, der> C++ wirklich verstehen will, durchaus sinnvoll, auch C zu verstehen.
... wer das Superset C++ verstehen will, muß natürlich auch das Subset C
erlernen. Es erscheint mir trotzdem widersinnig, sich ein Buch über C zu
kaufen, obwohl man eigentlich C++ lernen will. Die C-Grundlagen werden
aufgrund der genannten Super- und Subset-Beziehung der beiden Sprachen
schließlich auch in jedem C++-Buch behandelt.
Wenn man erst C lernt und dann C++ anfängt muss man die ganzen
schlechten C-Angewohnheiten wieder un-lernen. Daher ist es schon
sinnvoll, direkt mit C++ anzufangen. Gute C++ Bücher bringen das so von
Anfang an bei, dass man kein C braucht. Falls man später noch C für
irgendwas können muss, schaut man sich einfach an welche Teile von C++
auch C sind, das ist dann simpel.
Rufus Τ. F. schrieb:> Nicht vom hier geschilderten Problem unterscheidet sich zwischen C und> C++.>> Die Grundlagen sind ziemlich lang die gleichen; es ist für jemanden, der> C++ wirklich verstehen will, durchaus sinnvoll, auch C zu verstehen.
Wer wirklich C++ neu lernen möchte, sollte m.E. zunächst auf den
C-Anteil verzichten. Jemand der das ganz gut auf den Punkt gebracht hat,
ist K. Gregory in ihrem Vortrag "Stop teaching C" (der leider oft falsch
verstanden wird):
https://www.youtube.com/watch?v=YnWhqhNdYyk
Es geht nicht darum, C in irgendeiner Weise schlecht zu machen, sondern
darum, zunächst in einer anderen, ja abstrakteren Denkschule zu
beginnen. Es können zunächst Details außer Acht gelassen werden: dies
erleichtert den Blick für das Ganze und ermöglicht einen schnelleren
Fortschritt.
> In nur wenigen Bereichen verhält sich C-Code anders als als C++-Code> interpretierter C-Code.
C++ hat oftmals die "einengendere" Sichtweise, das klassische Beispiel:
unions. Wenn man also das C Verhalten zunächst gewohnt ist, schleicht
sich somit rasch UB ein. Andersherum ist m.E. besser.
Das gilt auch generell: zunächst sollte man die Sprache in einer
"geschützten" Umgebung, d.h. in einer Laufzeitumgebung in einem OS wie
Linux oder Windows kennen lernen, bevor man sich auf die µC stürzt
(falls der TO das in diesem Thread überhaupt will).
Ich arbeite ja gerade ein C++ Buch durch daher auch meine Frage. Das
Thema "extern" Variable wurde nur kurz angerissen.
"extern" sei häufig in Code mit zu vielen globalen Variablen anzutreffen
und man solle diese vermeiden aus diversen Gründen.
cpp schrieb:> Das Thema "extern" Variable wurde nur kurz angerissen.
Wie Definition und Deklaration funktionieren, sollte es aber trotzdem
beschreiben. Das ist ja nicht nur für globale Variablen relevant.
olo schrieb:> Und der Sinn von extern erschließt sich mir nicht so recht. Denn ich> kann doch auch einfach global> ...> int v;> ...>> schreiben, das ist eine Deklaration ohne Definition.
Nein, das ist sowohl eine Deklaration, als auch eine Definition.
1
externintv;
wäre eine Deklaration ohne Definition.
> Oder wird v ohne extern trotzdem automatisch initialisiert?
Ja, sofern das außerhalb einer Funktion oder Klasse steht, wird v auch
automatisch mit 0 initialisiert.
Rolf M. schrieb:> Ja, sofern das außerhalb einer Funktion oder Klasse steht, wird v auch> automatisch mit 0 initialisiert.
Ok das kann ich dann mal ausprobieren.