[gelöst] C++ programmieren unter Anjuta (Debian 6)
-
Klaus82 schrieb:
Mein Problem ist, dass ich weder in der Schule noch an der Uni Informatik gehört hatte. Es hat sich bei meiner Arbeit aber ergeben, dass ich Programmieren muss. Nicht schlimm, die Herausforderung nehme ich an.
Da frage ich mich was das für eine Firma ist, die Mitarbeiter für Aufgaben anstellt, für die sie gar nicht qualifiziert sind und dann auch noch erwartet, daß diese Mitarbeiter diese Aufgaben lösen können?
Wieso stellt die Firma in der du arbeitest nicht einfach entsprechende Fachkräfte ein?
Was soll das jetzt mit deiner Erwartung, daß du mal so auf die schnelle C++ lernen und später Software entwickeln könntest?
Nur mal so zur Info.
Um C++ einigermaßen gut zu können, braucht man etwa 10 Jahre Erfahrung und Übung.
Um dann anschließend komplette Software zu entwickeln, braucht man dann noch mal deutlich mehr Hintergrundwissen.
Mit dem reinen lernen einer Programmiersprache ist es also nicht getan.Ein Informatikstudium dauert nicht ohne Grund 3-5 Jahre.
Das ganze ist für mich nun aber ein zweischneidiges Schwert. Zum Einen muss ich natürlich vorwärts kommen, dass ich auch Ergebnisse liefere und mein Chef sich nicht fragt, für was sie mich eigentlich bezahlt.
Du wirst scheitern.
C++ lernst du nicht in 10 Tagen.Vielleicht kriegst du mit viel Glück ein undefiniertes etwas zusammen, das irgendwie tut, mit Klebeband und Bindfäden zusammengeflickt ist, aber ordentliche Software wird das nicht sein.
Dein Chef muß unqualifiziert genug sein, damit er dir so ein Machwerk dann abnimmt.
Wenn dein Chef auch so ein Auto bauen würde, dann gute Nacht.Zum Anderen, möchte ich natürlich aber auch rückwärts arbeiten (für was man i.d.R. weniger bezahlt wird), d.h. ich würde gerne genauer verstehen was ich da tue.
Dann besorg dir entsprechende Literatur.
C++ lernst du nicht, in dem du hier solche Fragen stellst.Ich habe jetzt das Problem, dass ich ein wenig Heimarbeit einrichten möchte und habe meinen PC mit Debian 6 aufgesetzt. Im Büro verwende ich zwar Netbeans als IDE, doch hier zu Hause habe ich mir jetzt mal Anjuta angesehen, weil ich beim Stöbern auf der Debian Homepage den Eindruck habe, dass es schlanker ist, weil nur für C++ zuständig?
Oh je ne me, selbst da fehlt das Rüstzeug.
Tue dir selbst einen Gefallen, laß es und sag deinem Chef er soll die Arbeit an eine Person weiterreichen, die dafür auch qualifiziert ist.
Kann mir jemand helfen, wie ich am Besten Land sehe?

Gruß,
Klaus.Befolge das was ich hier oben geschrieben habe.
Und Anjuta ist meiner Meinung nach nicht die Beste IDE für C++, auch nicht unter Linux.
-
Okay,
und nach dieser herben aber konstruktiven Kritik wieder weiter im Programm.

Mein bisheriger Wunsch war einen Sourcecode zu kompilieren ohne ein Projekt anlegen zu müssen.
Da bin ich z.B. hier fündig geworden. Ich habe also mittels gedit einen einfachen Code geschrieben und in der Konsole mittels
g++ -Wall -pedantic -ansi -o ionization ionization.cppdas ganze kompiliert.
Anschließend kann ich dann das Programm in der Konsole mittels
./ionizationausführen.
Klappt alles wunderbar!

Jetzt frage ich mich natürlich, was im Unterschied dazu ein ganzes Projekt sein soll, wie es weiter oben oder eben hier mit Autotools beschrieben wird.
Wozu der Umstand über die Reihenfolge./configure > make > make installIch schätze mal, dass dieser zweite Weg den ersten enthält. Denn wenn ich die configure Datei aufrufe, so wird ja irgendwie ein Kompiler gcc aktiviert.
Also wird das ganze kompiliert, was ich manuell oben über die Eingabe mittelsg++ -Wall -pedantic -ansi -o ionization ionization.cppmache, oder nicht?
Diese Sache mit make und make install sorgt dann nur dafür, dass ich die Datei von jedem Verzeichnis aus aufrufen kann.
Doch wozu das alles? Ich meine dieser zweite Weg fängt ja gleich an ganze Verzeichnisse anzulegen und nennt sich sicherlich nicht umsonst 'building project'.
Gruß,
Klaus.
-
Ich habe also mittels gedit einen einfachen Code geschrieben und in der Konsole mittels
Nimm Geany:
http://www.geany.org/Doch wozu das alles?
http://de.wikipedia.org/wiki/GNU_Build_System
http://www.developingprogrammers.com/index.php/2006/01/05/autotools-tutorial/
http://www.ijon.de/comp/tutorials/makefile.html
http://de.wikipedia.org/wiki/CMake
-
Hi Ohjemene,
Ohjemene schrieb:
Nimm Geany:
http://www.geany.org/Und warum?
Du hattest dich vorher gegen Anjuta ausgesprochen
Ohjemene schrieb:
Und Anjuta ist meiner Meinung nach nicht die Beste IDE für C++, auch nicht unter Linux.
Doch warum jetzt für Geany?
Gruß,
Klaus.
-
Doch wozu das alles?
Naja, bei einer Datei ohne externe Abhängigkeiten scheint das natürlich unnötig kompliziert. Aber die meisten Projekte bestehen aus sehr viel Code und den teilt man dann sinnvollerweise in mehrere Dateien auf und man benutzt in den meisten Fällen auch externe Abhängigkeiten. ./configure sorgt nun dafür, dass die ganzen externen Abhängigkeiten überprüft und aufgelöst werden. make sorgt dafür, dass das ganze Projekte (also jede Datei und nur wenn Änderungen vorliegen) gebaut wird und make install installiert das ganze. Das Konzept ist also schon sinnvoll.
-
Hm,
verstehe. Na ja, die Frage ist wahrscheinlich, ob ich im Alleingang so komplexe Codes baue.
Wenn ich mir jetzt allerdings meinen Code so ansehe. Ich bin schon versucht viele Definitionen von physikalischen Konstanten oder Funktionen in header Dateien auszulagern.Zumindest dachte ich, dass das auch in die Richtung der Idee des Objekt orientierten Programmierens geht. Man bastelt ein 'Objekt', definiert den In- und Output und behandelt es dann als Blackbox. Somit kann man die Programmierung von solch einzelnen Teilen weitergeben, muss es anschließend nur einbinden und kann es aufrufen.
Und es hat den Vorteil, dass ich bei Änderungen nur in den Objekten selbst was ändern muss und nicht meinen endlosen langen Quellcode durchsuchen muss.Wie gesagt, bisher habe ich viele Programmteile auch ausgelagert:
#include<iostream> #include<cmath> #include<fstream> // Numerical Recipes #include</home/klaus/NumericalRecipes/code/nr3.h> #include</home/klaus/NumericalRecipes/code/ran.h> #include</home/klaus/NumericalRecipes/code/roots.h> // personal header files #include</home/klaus/Water/HeaderFiles/F1.h> #include</home/klaus/Water/HeaderFiles/F2.h> #include</home/klaus/Water/HeaderFiles/physicalConstants.h> #include</home/klaus/Water/HeaderFiles/alpha.h> #include</home/klaus/Water/HeaderFiles/beta.h> #include</home/klaus/Water/HeaderFiles/gamma.h> #include</home/klaus/Water/HeaderFiles/delta.h> #include</home/klaus/Water/HeaderFiles/totalIonizationCrossSection.h> #include</home/klaus/Water/HeaderFiles/diffIonizationCrossSection.h> #include</home/klaus/Water/HeaderFiles/totalElasticScatteringCrossSection.h> #include</home/klaus/Water/HeaderFiles/diffElasticScatteringCrossSection.h>Nur leider habe ich feststellen müssen, dass die header Dateien eben in der richtigen Reihenfolge stehen müssen.
Z.B. verwendet die header Datei totalElasticScatteringCrossSection.h Elemente aus apha.h, beta.h, gamma.h. und delta.h.
Aus diesem Grund müssen die weiter vorne stehen.Aber ich 'erstelle' alles per Knopfdruck mit der einfachen Kommandozeile
g++ -Wall -pedantic -ansi -o "%e" "%f"Also nichts mit
./configure > make > make installOder läuft das beim Erstellen im Hintergrund ohne, dass ich es mitbekomme?
Gruß,
Klaus.
-
Klaus82 schrieb:
Aber ich 'erstelle' alles per Knopfdruck mit der einfachen Kommandozeile
g++ -Wall -pedantic -ansi -o "%e" "%f"Also nichts mit
./configure > make > make installOder läuft das beim Erstellen im Hintergrund ohne, dass ich es mitbekomme?
Gruß,
Klaus.na schau dir einfach mal den dazugehörigen makefile im editor an

kann falsch sein, aber irgendwie glaub ich, du hast das erstellen noch nicht durchdacht. schau dir dazu folgende begriffe an: präprozessor, compiler, linker. in dieser reihenfolge.
-
Klaus82 schrieb:
Hm,
verstehe. Na ja, die Frage ist wahrscheinlich, ob ich im Alleingang so komplexe Codes baue.Hat nix mit komplex zu tun. Wenn du objektorientiert C++ programmierst, hast du normalerweise pro Klasse einen Header und ein Sourcefile, dann noch ein Sourcefile für die main. Schon bei den einfachsten Projekten musst du dich also mit getrennter Compilierung und darauffolgendem Linken auseinandersetzen.
Nur leider habe ich feststellen müssen, dass die header Dateien eben in der richtigen Reihenfolge stehen müssen.
Z.B. verwendet die header Datei totalElasticScatteringCrossSection.h Elemente aus apha.h, beta.h, gamma.h. und delta.h.
Aus diesem Grund müssen die weiter vorne stehen.Nee, totalElasticScatteringCrossSection.h sollte alles inkludieren, was es braucht.
Aber ich 'erstelle' alles per Knopfdruck mit der einfachen Kommandozeile
g++ -Wall -pedantic -ansi -o "%e" "%f"%e %f? Sagt mir leider nichts.
-
Bashar schrieb:
Klaus82 schrieb:
Hm,
verstehe. Na ja, die Frage ist wahrscheinlich, ob ich im Alleingang so komplexe Codes baue.Wenn du objektorientiert C++ programmierst, hast du normalerweise pro Klasse einen Header und ein Sourcefile, dann noch ein Sourcefile für die main.
Okay,
ist immer viel auf einmal an Infos und dann reden wir noch nicht über guten Programmierstil.Wenn ich das soweit richtig verstanden habe, dann beginne ich in einer header Datei zunächst mit der sogenannten Deklaration, d.h. ich führe zunächst eine Größe wie eine Funktion erstmal ein.
// header.h double function (double x);In der c oder cpp Datei binde ich die Header Datei zunächst ein und fülle die deklarierten Elemente mit Leben.
// function.cpp #include<header.h> double function (double x){ return x*x; }Und anschließend muss natürlich jede Datei in meine Hauptdatei, wo alle Fäden zusammenführen.
// main.cpp #include<function.cpp> // ... HauptteilKann man das so sehen?
Bashar schrieb:
Aber ich 'erstelle' alles per Knopfdruck mit der einfachen Kommandozeile
g++ -Wall -pedantic -ansi -o "%e" "%f"%e %f? Sagt mir leider nichts.
Entschuldige, das ist der Syntax von Geany für die Kommandozeile zum Erstellen.
Dabei steht wohl "%e" als Platzhalter für den Dateiname später, wobei die Endung c oder cpp gerade weggelassen wurde, während "%f" die zu kompilierende Datei ist.Viele Grüße,
Klaus.
-
Klaus82 schrieb:
Wenn ich das soweit richtig verstanden habe, dann beginne ich in einer header Datei zunächst mit der sogenannten Deklaration, d.h. ich führe zunächst eine Größe wie eine Funktion erstmal ein.
// header.h double function (double x);So kann man das sehen, allerdings stellt sich da ja automatisch die Frage nach dem Warum. Es ist eher so: Du möchtest die Funktion in einem Sourcefile definieren und in einem anderen aufrufen, also muss sie nach außen bekannt gemacht werden. Dazu schreibst du eine Deklaration.
In der c oder cpp Datei binde ich die Header Datei zunächst ein und fülle die deklarierten Elemente mit Leben.
// function.cpp #include<header.h> double function (double x){ return x*x; }Ja. Außer dass man beim Include von eigenen "header.h" schreibt. Die <...>-Syntax ist für Header der Standardlibrary u.ä. gedacht. Der technische Unterschied liegt darin, ob und wie der Include-Pfad berücksichtigt wird.
Und anschließend muss natürlich jede Datei in meine Hauptdatei, wo alle Fäden zusammenführen.
// main.cpp #include<function.cpp> // ... HauptteilKann man das so sehen?
Nein, du bindest normalerweise keine cpp-Dateien ein. (Wo lernt man sowas?) Du compilierst alle cpp-Dateien getrennt. Inkludieren tust du nur Headerdateien.
Das läuft auf der Kommandozeile zu Fuß folgendermaßen. Zuerst getrennte Compilierung aller cpp-Dateien:
g++ -Wall -ansi -c foo.cpp g++ -Wall -ansi -c bar.cpp ...Es entstehen lauter gleichnamige .o-Dateien. In einem zweiten Schritt werden die nun zusammengelinkt:
g++ -o meinProgramm foo.o bar.o ...Das hat den Vorteil, dass man nur die Dateien neu compilieren (und dann wieder alles linken) muss, die sich geändert haben oder bei denen sich Änderungen aus eingebundenen Headerdateien auswirken. Ich arbeite hier z.B. an einem Projekt mit einigen Tausend Quelldateien, wenn ich da nach jeder Änderung erstmal eine halbe Stunde Pause machen könnte wäre das auch nur am Anfang nett.
An der Stelle kommen Makefiles oder Projekte usw. ins Spiel, weil du normalerweise das nicht alles von Hand machen willst. Du willst ein Tool, das mehr oder weniger automatisch nur die Dateien compiliert, die compiliert werden müssen, und alles zusammenlinkt.
-
Ah,
ich glaube langsam verstehe ich.

Ich habe leider keine Ausbildung in Richtung Informatik genossen, weder in der Schule noch während des Physik Studiums als Nebenfach o.ä. Das rächt sich jetzt ein wenig.
Ich hatte kurz vor dem Diplom ein wenig Labview programmiert [1] und damit erstmals auch generell programmiert [2].
Jetzt bin ich aus der Experimental- in die theoretische Physik übergewechselt, d.h. Mathematik, Numerik und Programmieren als Werkzeug, wenn man so möchte.
Und da ich gerne mehr verstehe als Knöpfchen drücken im Sinne von "jetzt spuckt er mir das Ergebnis der Formel aus, die ich reingekloppt habe" bin ich jetzt vermehrt an C++ selbst interessiert samt dem was dazugehört wie Compiler (und Linker, usw.)
Natürlich werde ich nie das Verständnis eines Informatikers erreichen, doch würde ich gerne so viel verstanden haben wie möglich.
Und da ich jetzt von Windows auf Linux umgestiegen bin, zwinge ich mich durch die Eingabe mittels Konsole immer mehr verstehen zu müssen.Natürlich kann ich es mir irgendwann einfach machen, indem ich mir eine Makefile bastle (oder ein shell skript?), aber dann weiß ich wenigstens was die Einträge bedeuten.
Gruß,
Klaus.[1] Falls das für Puritaner programmieren ist.

[2] Okay, bis auf den BASIC programmierbaren Taschenrechner meines Vaters, dem ich dann zu Schulzeiten die abc Formel einprogrammiert habe.
-
Bashar schrieb:
Nein, du bindest normalerweise keine cpp-Dateien ein. (Wo lernt man sowas?) Du compilierst alle cpp-Dateien getrennt. Inkludieren tust du nur Headerdateien.
Wobei ich in diesem Kontext gleich noch eine Frage nachschieben möchte:
Ich habe in einem anderen Thread geschrieben, dass ich jetzt versuche mit der GSL zu arbeiten [1].
Wenn man nun aber einen Blick in das Handbuch, genauer auf das Beispiel wirft, so sieht man, dass dort in eine Datei sowohl header- als auch c-Dateien includiert werden:
#include <stdio.h> #include <gsl/gsl_errno.h> #include <gsl/gsl_math.h> #include <gsl/gsl_roots.h> #include "demo_fn.h" #include "demo_fn.c" int main (void) { int status; int iter = 0, max_iter = 100; const gsl_root_fsolver_type *T; gsl_root_fsolver *s; double r = 0, r_expected = sqrt (5.0); double x_lo = 0.0, x_hi = 5.0; gsl_function F; struct quadratic_params params = {1.0, 0.0, -5.0}; // und so weiterWie ist das zu verstehen?
Gruß,
Klaus.[1] Daraus ist ja auch erst die Problematik mit dem Compiler und Linker entstanden.
-
Klaus82 schrieb:
Hi Ohjemene,
Ohjemene schrieb:
Nimm Geany:
http://www.geany.org/Und warum?
Du hattest dich vorher gegen Anjuta ausgesprochen
Doch warum jetzt für Geany?
Weil Geany ein zum Progammieren guter Editor ist, deutlich besser als Gedit.
Anjuta ist eine IDE, eine IDE mit einem Editor zu vergleichen ist wie Apfel und Birnen.Und ich halte es für den Anfang nicht für falsch, erstmal nur einen Editor zu benutzen. Wenn man dies tut, dann sollte man allerdings einen guten Editor nehmen. Geany ist so einer.
Wie gesagt, bisher habe ich viele Programmteile auch ausgelagert:
#include<iostream> #include<cmath> #include<fstream> // Numerical Recipes #include</home/klaus/NumericalRecipes/code/nr3.h> #include</home/klaus/NumericalRecipes/code/ran.h> #include</home/klaus/NumericalRecipes/code/roots.h> // personal header files #include</home/klaus/Water/HeaderFiles/F1.h> #include</home/klaus/Water/HeaderFiles/F2.h> #include</home/klaus/Water/HeaderFiles/physicalConstants.h> #include</home/klaus/Water/HeaderFiles/alpha.h> #include</home/klaus/Water/HeaderFiles/beta.h>Gewöhne dir ab, in deinem Quellcode absolute Pfade zu verwenden.
Außerdem gehören eigene Headerdateien in Anführungszeichen gesetzt.
Spitze Klammern sind nur für Headerdateien gedacht, die Systemweit z.B. unter /usr/include installiert sind.
In der Regel benutzt man diese für Bibliotheken.Ich habe in einem anderen Thread geschrieben, dass ich jetzt versuche mit der GSL zu arbeiten [1].
Bei weitergabe deines Programms mußt du dann auch den Quellcode unter die GPL stellen und mitliefern, ich hoffe du weißt das.
Die GSL steht nämlich nicht unter der LGPL, sondern unter der GPL.
-
Alles klar,
aber jetzt bitte nochmal zurück zu meiner Fragestellung.
Ich verstehe das Argument von Bashar sehr gut, der da schreibt:
Bashar schrieb:
Nein, du bindest normalerweise keine cpp-Dateien ein. (Wo lernt man sowas?) Du compilierst alle cpp-Dateien getrennt. Inkludieren tust du nur Headerdateien.
Das läuft auf der Kommandozeile zu Fuß folgendermaßen. Zuerst getrennte Compilierung aller cpp-Dateien:
g++ -Wall -ansi -c foo.cpp g++ -Wall -ansi -c bar.cpp ...Es entstehen lauter gleichnamige .o-Dateien. In einem zweiten Schritt werden die nun zusammengelinkt:
g++ -o meinProgramm foo.o bar.o ...Was mich jetzt nur ein wenig wundert ist die Fragestellung, dass die zuvor einzeln kompilierten Dateien doch durchaus miteinander verflochten sind. Also mit der obigen Bezeichnung kann es ja sein, dass ich etwas in foo.cpp kompiliere, was ich dann in bar.cpp verwende.
Aus diesem Grund stelle ich mir gerade naiv vor, dass doch beim kompilieren von bar.cpp ein Fehler entstehen müsste.
Natürlich macht es intuitiv Sinn, dass ich dann einen Linker aufrufe, der die Dateien anschließend verknüpft. Doch das findet ja nach dem kompilieren statt. Und so beißt sich für mich die Katze irgendwie in den Schwanz.

Ich kenne es bisher nur von LaTex, dass ich einzelne Kapitel bearbeite und so nicht immer das ganze Dokument kompilieren muss. Doch dann bleiben Querverweise erstmal leer oder werden mit einem ? gefüllt.
D.h. ich kann Kapitel gar nicht einzeln kompilieren, wenn sie anschließend zu einem Gesamtdokument zusammengefügt werden sollen.Wie passt das denn zusammen?
Gruß,
Klaus.
-
Es gibt eben die "One Definition Rule". Du darfst für jedes Symbol (Variable, Funktion, Klasse, Struktur, etc.) nur eine Definition (also Implementierung haben) aber beliebig viele Deklarationen. Der Linker löst dann am Ende ohne Probleme die Symbole (LaTeX mäßig eben die ?? bei den Verweisen) auf.
Bsp
// foo.hpp #ifndef FOO_HPP #define FOO_HPP // Include guards um Mehrfacheinbindung zu verhindern extern void foo(); // Deklaration #endif// foo.cpp #include "foo.hpp" // Beachte: Keine absoluten Pfade! Niemals nie! #include <iostream> void foo() { // Definition std::cout << "Hello World\n"; }#include "foo.hpp" int main() { foo(); // Der Compiler generiert hier sozusagen "??" und der Linker löst das auf in einen Aufruf von foo }g++ -Wall -Wextra -pedantic -ansi -c foo.cpp
g++ -Wall -Wextra -pedantic -ansi -c main.cpp
g++ foo.o main.o -o foo
./foo
Hello World
-
Ich denke so langsam verstehe ich.
rüdiger schrieb:
#include "foo.hpp" int main() { foo(); // Der Compiler generiert hier sozusagen "??" und der Linker löst das auf in einen Aufruf von foo }Was mir hier erst auffällt, dass du nur header Dateien verwendest!
Das heißt, wenn ich in einem cpp Code eine Variable oder Methode verwenden möchte, dass du muss ich die entsprechende header Datei included sein, in der die Deklaration steht.
Die Deklaration alleine reicht dem Compiler allerdings noch nicht, da erst die Definition die Information liefert was die Methode auch tut und somit den Compiler zufriedenstellt.Ich habe nochmal ein Minimalbeispiel erstellt.
// linear_function.h double linear_function(double x);und
// linear_function.cpp #include "linear_function.h" double linear_function(double x) { double m = 2; double b = -2; return m*x + b; }Das ganze wird nun hier verwendet
// composition_function.h double composition_function(double x);Und schließlich die Definition, wobei ich nur die header Datei verwende!
// composition_function.cpp #include "composition_function.h" #include "linear_function.h" double composition_function(double x) { return x * linear_function(x); }Jetzt bin ich aber doch ein wenig verwirrt. Ich kompiliere zunächst die compositin_functin.cpp
g++ -Wall -pedantic -ansi -c composition_functin.cppUnd bekomme keine Fehlermeldung! Wieso das denn? Ist es die Option -c, welche darauf hinweist, dass noch nicht gelinkt werden soll, sprich noch keine Gedanken über Abhängigkeit gemacht werden sollen?
Der Kompiler weiß durch include "linear_function.h", dass die verwendete Referenz zwar deklariert ist, interessiert sich aber noch nicht für deren Definition?Ich habe include "linear_function.h" mal herausgenommen mittels //, dann meckert er
:~/Cpp/Minimalbeispiele$ g++ -Wall -pedantic -ansi -c composition_function.cpp composition_function.cpp: In function ‘double composition_function(double)’: composition_function.cpp:7: error: ‘linear_function’ was not declared in this scopeAha! Sehr interessant. Also schnell wieder hinein.
Was mich jetzt noch wundert, warum ich nicht linear_function.o und composition_function.o linken kann?
:~/Cpp/Minimalbeispiele$ g++ linear_function.o composition_function.o -o composition_function /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o: In function `_start': (.text+0x20): undefined reference to `main' collect2: ld returned 1 exit statusIch nehem an, es liegt daran, dass in C/C++ alles in einer int main(){} Umgebung liegen muss? Ist das einfach Konvention? Also schnell noch eine main file geschrieben:
#include <iostream> #include "linear_function.h" #include "composition_function.h" using namespace std; int main() { double value = 3; cout << "Result = " << composition_function(value) << endl; return 0; }Kompiliert und dann funktioniert auch das linken wieder und ich bekomme ein Ergebnis:
:~/Cpp/Minimalbeispiele$ g++ -Wall -pedantic -ansi -c main.cpp :~/Cpp/Minimalbeispiele$ g++ main.o linear_function.o composition_function.o -o main :~/Cpp/Minimalbeispiele$ ./main Result = 12 :~/Cpp/Minimalbeispiele$Spielt die Abhängigkeit beim Linken eigentlich eine Rolle, oder schafft der Kompiler das von alleine?
Bin ich langsam vom Verständnis her auf dem richtigen Weg?

Viele Grüße und danke für eure Hilfe,

Klaus.
-
Das heißt, wenn ich in einem cpp Code eine Variable oder Methode verwenden möchte, dass du muss ich die entsprechende header Datei included sein, in der die Deklaration steht.
Die Deklaration alleine reicht dem Compiler allerdings noch nicht, da erst die Definition die Information liefert was die Methode auch tut und somit den Compiler zufriedenstellt.Die Deklaration muss nicht in einem Header stehen
// bar.cpp #include <iostream> void foo() { std::cout << "Hallo Welt\n"; }// foo.cpp extern void foo(); int main() { foo(); }geht genauso. Und der Compiler braucht nur die Deklaration. Erst der Linker muss dann wissen wo er die Definition finden kann, damit der den Aufruf von foo an die richtige Stelle setzt.
Ist es die Option -c, welche darauf hinweist, dass noch nicht gelinkt werden soll, sprich noch keine Gedanken über Abhängigkeit gemacht werden sollen?
Ja
Was mich jetzt noch wundert, warum ich nicht linear_function.o und composition_function.o linken kann?
Ein ausführbares Programm braucht eine main-Funktion.
-
Hi,
rüdiger schrieb:
Und der Compiler braucht nur die Deklaration. Erst der Linker muss dann wissen wo er die Definition finden kann, damit der den Aufruf von foo an die richtige Stelle setzt.
Alles klar.
Aber was mich nach wie vor wundert: Cpp Dateien einbinden oder nicht?
Ich bin immernoch irritiert von Bashars Aussage, der da schreibt:
Nein, du bindest normalerweise keine cpp-Dateien ein. (Wo lernt man sowas?) Du compilierst alle cpp-Dateien getrennt. Inkludieren tust du nur Headerdateien.
Aber bei dem Thread zum Minimalbeispiel der GSL binden wir cpp Dateien ein und es hat niemanden gestört.
Ich kann das Beispiel auch mal 'rüberholen':
Klaus82 schrieb:
rng.h
double get_random_number();Dann das ganze in eine cpp-Datei eingebunden:
rng.cppdouble get_random_number() { const gsl_rng_type* T; gsl_rng* r; gsl_rng_env_setup(); T = gsl_rng_default; r = gsl_rng_alloc (T); return gsl_rng_uniform (r); gsl_rng_free (r); }Schließlich habe ich das ganze in ein Hauptprogramm eingebunden, worin ich schließlich eine Zufallszahl verwenden möchte:
main.cpp#include<iostream> #include<stdio.h> // GSL #include</usr/local/include/gsl/gsl_rng.h> // personal header files #include "rng.h" #include "rng.cpp" using namespace std; int main(){// cout << "Random number in [0,1[ : " << get_random_number() << endl; return 0; }Gruß,
Klaus.
-
Klaus82 schrieb:
Aber was mich nach wie vor wundert: Cpp Dateien einbinden oder nicht?
Die Frage hab ich dir schon beantwortet.
Ich bin immernoch irritiert von Bashars Aussage, der da schreibt:
Nein, du bindest normalerweise keine cpp-Dateien ein. (Wo lernt man sowas?) Du compilierst alle cpp-Dateien getrennt. Inkludieren tust du nur Headerdateien.
Achso, du wartest darauf, dass jemand dir die Antwort gibt, die du hören willst.
Aber bei dem Thread zum Minimalbeispiel der GSL binden wir cpp Dateien ein und es hat niemanden gestört.
rüdiger dürfte das einfach übersehen haben, wofür ja auch seine Antwort, "Du hast vergessen rng.cpp zu kompilieren und zu linken!" spricht. Sonst hat sich dazu keiner geäußert.
-
Hi,
Bashar schrieb:
Achso, du wartest darauf, dass jemand dir die Antwort gibt, die du hören willst.

Bashar schrieb:
Aber bei dem Thread zum Minimalbeispiel der GSL binden wir cpp Dateien ein und es hat niemanden gestört.
rüdiger dürfte das einfach übersehen haben, wofür ja auch seine Antwort, "Du hast vergessen rng.cpp zu kompilieren und zu linken!" spricht.
Okay.
Bashar schrieb:
Sonst hat sich dazu keiner geäußert.
Das ist ja nach wie vor der Punkte an dem ich knabbere. Rüdigers Aussage scheint zu bedeuten, dass es ein no-go ist cpp-Dateien einzubinden. In dem GSL Beispiel für Zufallszahlen wird es aber getan.
Das lässt für mich den Schluß zu, dass es prinzipiell möglich ist nur scheinbar schlecher Programmierstil?
Ich möchte es einfach einordnen können.

Gruß,
Klaus.