Forum: PC-Programmierung Build in C++ klappt nicht


von cpp (Gast)


Lesenswert?

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
1
#include "my.h"
2
#include "../../std_lib_facilities_C++11.h"
3
4
// Definitions
5
void print_foo()
6
{
7
    cout << foo << '\n';
8
}
9
10
void print(int i)
11
{
12
    cout << i << '\n';
13
}



use.cpp
1
#include "my.h"
2
#include <iostream>
3
4
int main()
5
{
6
    print_foo();
7
    print(99);
8
}



my.h
1
// Declarations
2
extern int foo;
3
void print_foo();
4
void print(int);

von Martin B. (ratazong)


Lesenswert?

Du hast foo nirgends angelegt. Es ist nur als extern my.h deklariert.

von Dr. Sommer (Gast)


Lesenswert?

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.

von cpp (Gast)


Lesenswert?

Erledigt, sie ist jetzt in use.cpp definiert, aber immer noch dieselbe 
Fehlermeldung, diesmal sogar zweimal, einmal für use.cpp und my.cpp

use.cpp
1
#include "my.h"
2
#include <iostream>
3
4
int main()
5
{
6
    foo = 7;
7
    print_foo();
8
    print(99);
9
}

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


Lesenswert?

Wo genau ist sie definiert?

Ich seh da nur eine Benutzung.

Irgendwo musst du halt ein
1
int foo;

stehen haben.

von cpp (Gast)


Lesenswert?

Jörg W. schrieb:
> Ich seh da nur eine Benutzung.
>
> Irgendwo musst du halt ein
> int foo;
> stehen haben.

Wenn ich in use.cpp schreibe:
1
...
2
int foo = 7;
3
...

dann bekomme ich folgendes:
use.cpp: unused variable
my.o:my.cpp: undefined reference to 'foo'

Beitrag #5251616 wurde vom Autor gelöscht.
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Du musst sie natürlich auch global anlegen, nicht innerhalb von main().

von Rolf M. (rmagnus)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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.

von olo (Gast)


Lesenswert?

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.

von Daniel A. (daniel-a)


Lesenswert?

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.

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


Lesenswert?

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.

von PittyJ (Gast)


Lesenswert?

Man kann es immer noch kaufen:
https://www.amazon.de/Programming-Language-Prentice-Hall-Software/dp/0131103628/ref=sr_1_1?ie=UTF8&qid=1513922384&sr=8-1&keywords=kernighan+ritchie

und es hat schon tausenden Programmierern geholfen. Warum sollte es bei 
dir nicht klappen...

von Sheeva P. (sheevaplug)


Lesenswert?

PittyJ schrieb:
> Man kann es immer noch kaufen:
> 
https://www.amazon.de/Programming-Language-Prentice-Hall-Software/dp/0131103628/ref=sr_1_1?ie=UTF8&qid=1513922384&sr=8-1&keywords=kernighan+ritchie
>
> und es hat schon tausenden Programmierern geholfen. Warum sollte es bei
> dir nicht klappen...

Weil das ein Buch über die Sprache C ist, der TO aber C++ lernen will.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Sheeva P. (sheevaplug)


Lesenswert?

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.

von Dr. Sommer (Gast)


Lesenswert?

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.

von Wilhelm M. (wimalopaan)


Lesenswert?

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

von cpp (Gast)


Lesenswert?

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.

von olo (Gast)


Lesenswert?

Und der Sinn von extern erschließt sich mir nicht so recht. Denn ich 
kann doch auch einfach global
1
...
2
 int v; 
3
...

schreiben, das ist eine Deklaration ohne Definition. Oder wird v ohne 
extern trotzdem automatisch initialisiert?

von Rolf M. (rmagnus)


Lesenswert?

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
extern int v;
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.

von olo (Gast)


Lesenswert?

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.

von Ezechiel (Gast)


Lesenswert?

Bitte einmal pragma once in die Header Datei...

Beitrag #5258530 wurde von einem Moderator gelöscht.
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.