Kompilieren Modulierter C++ Programme

Fachdiskussionen rund um Themen und Veranstaltungen ohne Zuordnung zu einem bestimmten Semester (Allgemeine organisatorische und verwaltungstechnische Themen, die NICHT in unmittelbarem und direktem Zusammenhang mit einer Veranstaltung zu sehen sind, bitte in "Studienverwaltung allgemein" einsortieren!)

Moderator: (M) Mod.-Team Allgemein

Antworten
Tok
TalkING. Newbie
TalkING. Newbie
Beiträge: 2
Registriert: Mi, 19. Mai. 10, 13:42

Kompilieren Modulierter C++ Programme

Beitrag von Tok » Mi, 19. Mai. 10, 13:55

Heyho,

in einer Übung der Informatik für Ingenieure 2 soll man ein modulisiertes Programm kompilieren.
Es gibt drei Dateien: "main.cpp", "ausgabe.cpp" und "ausgabe.h".

Ich nutze Kdevelop auf Ubuntu 9.04 und bekomme das Programm nicht zum laufen. Fehler im Quelltext schließe ich aus.
(Aufgabe 1 Programmbeispiel 3 "Headerfiles")

Im Skript steht, mann soll die module separat kompilieren, aber bei "ausgabe.cpp" und "main.cpp" kommt jeweils die Fehlermeldung: "undefined reference to `ausgabe()'"

Somit wird das Programm bei mir nicht kompiliert und ich kann es deshalb auch nicht ausführen...

Wenn du ne Idee hast dann sag mal an bitte;-)
Vielen Dank im Vorraus!

Benutzeravatar
HerrSultan
Exzellenter Poster
Exzellenter Poster
Beiträge: 3115
Registriert: Mo, 07. Okt. 02, 13:12
Wohnort: Hamburg-Altona
Kontaktdaten:

Beitrag von HerrSultan » Mi, 19. Mai. 10, 16:53

Eine undefined reference kommt eigentlich nur, wenn man ein include vergessen hat. Das #include "ausgabe.h" muss in beiden cpp-Dateien drin stehen.

Benutzeravatar
NightStalker
TalkING. Champion
TalkING. Champion
Beiträge: 891
Registriert: Mo, 21. Okt. 02, 20:40
Wohnort: Downloadbereich

Beitrag von NightStalker » Mi, 19. Mai. 10, 19:22

"Undefined reference" deutet mehr auf 'nen Linkerfehler hin, weil ausgabe.cpp noch nicht als Object vorliegt. Aber da wir die Dateien ja nicht haben, können wir eh nur raten.

Hier mein raten:

ausgabe.h

Code: Alles auswählen

void ausgabe(void);
ausgabe.cpp

Code: Alles auswählen

#include "ausgabe.h"
#include <stdio>

void ausgabe&#40;void&#41;
&#123;
        printf&#40;"\nRTFM !\n"&#41;;
&#125;
main.cpp

Code: Alles auswählen

#include "ausgabe.h"

int main&#40;void&#41;
&#123;
        ausgabe&#40;&#41;;
        return 0;
&#125;
Fehler reproduzieren:

Code: Alles auswählen

g++ main.cpp
/tmp/ccehizFd.o&#58; In function `main'&#58;
main.cpp&#58;&#40;.text+0x12&#41;&#58; undefined reference to `ausgabe&#40;&#41;'
collect2&#58; ld returned 1 exit status
Korrekt ist kompilieren mit:

Code: Alles auswählen

g++ -c ausgabe.cpp -o ausgabe.o
g++ ausgabe.o main.cpp
Ausführen:

Code: Alles auswählen

./a.out 

RTFM !
Wie du das jetzt KDevelop beibringst, weiß ich auch nicht, ich würd so 'n Winzkram immer auf der Konsole machen, bis ich das der Entwicklungsumgebung beigebracht habe dauert es dreimal so lange.
Zuletzt geändert von NightStalker am Mi, 19. Mai. 10, 19:29, insgesamt 2-mal geändert.
-- Chrz&#261;szcz brzmi w trzcinie w Szczebrzeszynie.
-- &#22909;&#22909;&#23398;&#20064;&#65292;&#22825;&#22825;&#21521;&#19978;&#65281;

Benutzeravatar
NightStalker
TalkING. Champion
TalkING. Champion
Beiträge: 891
Registriert: Mo, 21. Okt. 02, 20:40
Wohnort: Downloadbereich

Beitrag von NightStalker » Mi, 19. Mai. 10, 19:26

In ausgabe.cpp muß das zweite #include die Datei stdio.h enthalten (mit Endung). In meinen Dateien steht das auch, aber Talking will das nicht akzeptieren. Irgendwie filtert er die Endung immer ... ultraseltsam.
-- Chrz&#261;szcz brzmi w trzcinie w Szczebrzeszynie.
-- &#22909;&#22909;&#23398;&#20064;&#65292;&#22825;&#22825;&#21521;&#19978;&#65281;

Tok
TalkING. Newbie
TalkING. Newbie
Beiträge: 2
Registriert: Mi, 19. Mai. 10, 13:42

Vielen Dank für die Antworten!

Beitrag von Tok » Do, 20. Mai. 10, 16:56

Hey NightStalker,
erstmal: Respekt! Den Quellcode hast du ziemlich gut erraten (ist ein triviales Programm, bin aber trotzdem beeindruckt!)

Ich kompiliere bisher ausschließlich mit der Konsole, und mit deiner Beschreibung für das Kompilieren und Ausführen funktioniert alles perfekt.

Somit bleibt nur noch die Frage: wieso das ganze? Wieso muss man es so machen? Gibt es dazu Literatur im Internet?

Die Endung "dateineame.o" kenne ich nicht... Handelt es sich dabei um Makefiles?
Dazu habe ich leider nichts im Skript gefunden. Ein Komilitone hat mir die Seite
http://openbook.galileocomputing.de/c_von_a_bis_z/
empfohlen, aber da gibt es auch keine Makefiles und es handelt sich alles um "C". Leider kann ich noch nicht richtige abschätzen in wiefern C und C++ sich unterscheiden... (ich weiß nur das alle C-Codes in C++ funktionieren sollen)

Vielen Dank fürs weiterhelfen!

P.S. weiß jemand wie man Kdevelop vertikal trennen kann, sodass links die Editoreben und rechts der Terminal ist? Bekomme das nur oben/unten getrennt, und das nervt weil man mega viel am scrollen ist...

Benutzeravatar
NightStalker
TalkING. Champion
TalkING. Champion
Beiträge: 891
Registriert: Mo, 21. Okt. 02, 20:40
Wohnort: Downloadbereich

Re: Vielen Dank für die Antworten!

Beitrag von NightStalker » Do, 20. Mai. 10, 18:56

Tok hat geschrieben: Somit bleibt nur noch die Frage: wieso das ganze? Wieso muss man es so machen? Gibt es dazu Literatur im Internet?
Guck dir an in welchen Schritten Programme übersetzt werden. Die Kurzfassung: Erst werden von jedem Programm die einzelnen Module kompiliert, die Ausgabe ist dann nicht-lauffähiger Object-Code (Endung .o normalerweise), welches aber schon assemblierter Maschinencode ist. Als letzter Schritt werden alle .o Dateien zu einem ausführbaren Programm zusammengelinkt, wobei dann natürlich auch alle Funktionen schon in kompilierter Form vorliegen müssen. Wenn nicht, gibt es genau die besagte Linkerfehlermeldung. Wenn du dagegen g++ nur auf die main.cpp losläßt, hat er keine Möglichkeit zu wissen, dass die ausgabe.cpp auch kompiliert werden muß, um die Referenz auf ausgabe() aufzulösen. Deshalb kompiliert man ausgabe.cpp vorher ohne sie zu linken (Option -c) und gibt die Objectdatei dann als zusätzliche Eingabedatei bei der vollständige Übersetzung (kompilieren und linken) von main.cpp an.

Die beiden Befehle die ich dir genannte habe, hättest du auch in drei verwandeln können, indem du erst beide .cpp Dateien nur mit -c bearbeitest und dann die Teile nur noch zusammenlinkst. Das Resultat ist dasselbe.

Makefiles sind Textdateien, die dem Compiler Abhängigkeiten zwischen den Modulen verraten, also genau dafür sorgen, dass die Dateien in der richtigen Reihenfolge kompiliert werden. Es reicht dann einfach make aufzurufen und alles andere wird automatisch bestimmt.

Der Code, den ich als Beispiel benutzt habe, ist ausschließlich C-Code aber wie du siehst schluckt der C++-Compiler ihn trotzdem problemlos. Bezüglich der Modularisierung und der Kompilierschritte unterscheiden sich C und C++ auch nicht, insofern gilt alles, was ich gesagt habe, für beide.
-- Chrz&#261;szcz brzmi w trzcinie w Szczebrzeszynie.
-- &#22909;&#22909;&#23398;&#20064;&#65292;&#22825;&#22825;&#21521;&#19978;&#65281;

Benutzeravatar
wildcard
TalkING. Superposter
TalkING. Superposter
Beiträge: 305
Registriert: Mo, 20. Sep. 04, 17:28

Beitrag von wildcard » Do, 20. Mai. 10, 20:35

Such dir ergänzend noch Infos zum Thema "Prototypen"...Das erklärt dir wieso man diese ".h" Dateien benötigt.

Harry
Moderator
Moderator
Beiträge: 799
Registriert: Do, 19. Jun. 03, 14:34
Wohnort: ::1
Kontaktdaten:

Re: Vielen Dank für die Antworten!

Beitrag von Harry » Fr, 21. Mai. 10, 10:00

Tok hat geschrieben:Hey NightStalker,
erstmal: Respekt! Den Quellcode hast du ziemlich gut erraten (ist ein triviales Programm, bin aber trotzdem beeindruckt!)
Das hätte ich von ihm auch kaum anders erwartet... ;)

Loliger
TalkING. Newbie
TalkING. Newbie
Beiträge: 1
Registriert: Fr, 29. Jun. 12, 23:04

Beitrag von Loliger » Fr, 29. Jun. 12, 23:09

Ich muss an dieser Stelle NightStalker ein besonderes Lob aussprechen. Ein wirklich gute kompakte und informative Erklärung. Dich hätte ich gerne als Professor!

Ich stecke nämlich bei einem sehr sehr ähnlichen Problem fest und werde mich jetzt ans Kompillieren machen. Dankeschön!
Take it easy

Antworten