mikrocontroller.net

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


Autor: cpp (Gast)
Datum:

Bewertung
-1 lesenswert
nicht 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
#include "my.h"
#include "../../std_lib_facilities_C++11.h"

// Definitions
void print_foo()
{
    cout << foo << '\n';
}

void print(int i)
{
    cout << i << '\n';
}



use.cpp
#include "my.h"
#include <iostream>

int main()
{
    print_foo();
    print(99);
}



my.h
// Declarations
extern int foo;
void print_foo();
void print(int);

Autor: Martin B. (ratazong)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast foo nirgends angelegt. Es ist nur als extern my.h deklariert.

Autor: Dr. Sommer (Gast)
Datum:

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

Autor: cpp (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
#include "my.h"
#include <iostream>

int main()
{
    foo = 7;
    print_foo();
    print(99);
}

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

Bewertung
0 lesenswert
nicht lesenswert
Wo genau ist sie definiert?

Ich seh da nur eine Benutzung.

Irgendwo musst du halt ein
int foo;

stehen haben.

Autor: cpp (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
...
int foo = 7;
...

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

Beitrag #5251616 wurde vom Autor gelöscht.
Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

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

Autor: Rolf Magnus (rmagnus)
Datum:

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

Autor: Dr. Sommer (Gast)
Datum:

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

Autor: olo (Gast)
Datum:

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

Autor: Daniel Abrecht (daniel-a)
Datum:

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

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

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

Autor: PittyJ (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Man kann es immer noch kaufen:
https://www.amazon.de/Programming-Language-Prentic...

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

Autor: Sheeva Plug (sheevaplug)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PittyJ schrieb:
> Man kann es immer noch kaufen:
> 
https://www.amazon.de/Programming-Language-Prentic...
>
> 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

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

Autor: Sheeva Plug (sheevaplug)
Datum:

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

Autor: Dr. Sommer (Gast)
Datum:

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

Autor: Wilhelm M. (wimalopaan)
Datum:

Bewertung
3 lesenswert
nicht 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):

Youtube-Video "CppCon 2015: Kate Gregory “Stop Teaching C""

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

Autor: cpp (Gast)
Datum:

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

Autor: olo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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. Oder wird v ohne 
extern trotzdem automatisch initialisiert?

Autor: Rolf Magnus (rmagnus)
Datum:

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

Autor: olo (Gast)
Datum:

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

Autor: Ezechiel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitte einmal pragma once in die Header Datei...

Beitrag #5258530 wurde von einem Moderator gelöscht.

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.

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