Diskussion:C++-Programmierung/ Einführung zum Buch/ Compiler
Text zur Benutzung des GCC
BearbeitenDies ist der (vorläufige) Text zum GCC. Der Text wird natürlich noch verbessert, schreibt mir doch bitte was ich noch verbessern kann.
Benutzung des GCC
BearbeitenGcc steht fuer Gnu Compiler Collection und ist eine Sammlung von Compilern, die Comnpiler für nicht nur C++, sondern für auch z.B. C und andere Sprachen beinhaltet. Er steht unter der Gnu General Public License (Gnu GPL), das heisst, GCC ist Opensource und jeder ist berechtigt, den Source Code einzusehen und zu verändern. Dieser Text geht auf die Benutzung von GCC unter Linux ein.
Auf fast allen Linux-Systemen sollte GCC schon standardmäßig installiert sein, falls nicht, können Sie GCC durch den Paketmanager Ihrer Distribution nachinstallieren.
Das ganze Programmpaket heißt GCC, da GCC aber auch z.B. C unterstützt, wüsste er ja nicht, ob C oder C++ benutzt werden soll.
Also gibt es verschiedene Befehle für den GCC, für C++ benutzen Sie g++ , der für C hieße gcc.
Aber jetzt ist Schluss mit der Theorie, schauen wir uns erst einmal die Benutzung von g++ an.
Im folgenden wird angenommen, dass eine Datei mit dem Namen prog.cpp vorhanden ist. In dieser Datei könnte z.B. folgendes stehen:
#include<iostream> using namespace std; int main() { cout << "Hello World\n"; }
Dieses Programm müssen Sie noch nicht verstehen (es gibt "Hello World" aus), es wird in Kapitel Hallo, du schöne Welt! erklärt werden. Nun tippen wir in eine shell folgendes ein:
g++ prog.cpp
g++ ist der Name des Programms, welches aufgerufen wird. prog.cpp ist der Name der Datei, die compiliert werden soll. Wenn man diesen Befehl abschickt, sieht man entweder Fehlermeldungen auf dem Bildschirm, oder aber man bekommt eine Datei mit dem Namen a.out . Manchmal bekommt man auch sogenannte "warnings", also Warnungen. Bei diesen Warnungen wird der Code zwar compiliert, allerdings sollte man trotzdem versuchen, warnungsfreie Programme zu schreiben. Ein Beispiel für eine Warnung könnte z.B. sein:
g++ prog.cpp prog.cpp: In function `int main()': prog.cpp:17: warning: comparison between signed and unsigned integer expressions
In diesem Beispiel würde die Warnung bedeuten, dass wir eine Zahl ohne Vorzeichen (unsigned) und eine mit Vorzeichen (signed) vergleichen, und zwar innerhalb der Funktion `int main()' , genauergesagt in Linie 17. Was unsigned und signed ist erfahren Sie im Kapitel Variablen, Konstanten und ihre Datentypen.
Allerdings gibt es auch einige, z.T. hilfreiche Warnungen, die nicht angezeigt werden. Um diese trotzdem zu sehen, kann man die Option -Wall hinzufügen.
g++ prog.cpp -Wall
Um sich noch mehr Warnungen anzeigen zu lassen (-Wall zeigt auch nicht alle an), kann man auch noch Wextra benutzen:
g++ prog.cpp -Wall -Wextra
Möchte man, dass das fertige Programm einen anderen Namen als a.out hat, so kann man das Programm umbenennen. Dies ist aber umstaendlich und nicht zu empfehlen. Ein viel eleganterer Weg ist die Benutzung der Option -o .
g++ prog.cpp -o tollername.out
Der Dateiname nach der Option -o gibt an, in welche Datei das compilierte Programm gespeichert werden soll. So erhält man in diesem Beispiel die ausführbare Datei tollername.out .
Sollten Sie sich einmal nicht mehr erinnern, was eine bestimmte Funktion bewirkte oder wie sie hieß, so können Sie g++ einfach nur mit der Option --help
aufrufen.
g++ --help
g++ gibt dann eine kurze Auflistung der Optionen aus. Wer gerne eine detailiertere Version hätte, kann auch das Manualprogramm man benutzen:
man g++
Allerdings ist diese Hilfe etwas lang (über 10 000 Zeilen...).
Außerdem gibt es noch eine übersichtliche Dokumentation bei info.
info g++
Jetzt sollten Sie erst einmal den Rest des Kapitels überspringen und mit Was ist Programmierung? weitermachen. Sobald Sie mit den ersten paar Kapiteln fertig sind, können Sie hierher zurückkehren und den Rest lesen.
Jetzt erst einmal etwas Theorie.
Was passiert überhaupt, wenn man g++ aufruft? Nun, als erstes wird der Code vom Präprozessor durchgeschaut und bearbeitet. (Natürlich bleibt Ihre Quelldatei, wie sie ist) Dabei werden z.B. Makros ersetzt und Kommentare gelöscht. Dieser bearbeitete Code wird dann vom Compiler in die Assemblersprache übersetzt. Die Assemblersprache ist auch eine Programmiersprache, welche aber nur die Maschienensprache so darstellt, dass ein Mensch Sie lesen kann. Schliesslich wird diese Assemblersprache von einem Assembler in Maschienencode umgewandelt. Zum Schluss wird noch der Linker aufgerufen, der das Programm mit den benutzten Bibliotheken "verbindet".
Darum - dass dies alles in korrekter Reihenfolge richtig ausgeführt wird - brauchen Sie sich nicht zu kümmern, g++ erledigt das alles für sie. Allerdings kann es manchmal nützlich sein, dass das Programm noch nicht gelinkt wird, z.B. wenn man mehrere Quelldateien hat. Dann kann man einfach dem g++ die Option -c mitgeben, z.B.
g++ prog.cpp -c
Durch diesen Aufruf erhalten wir eine Datei proga.o , die zwar compiliert und assembliert, aber noch nicht gelinkt ist. Deswegen wurde die Datei auch proga.o genannt, da ein compiliertes und assembliertes, aber nicht gelinktes Programm als Objektdatei vorliegt. Objektdateien bekommen bei Linux die Endung .o .
Bei g++ gibt es Unmengen von Optionen, mit denen man fast alles kontrollieren kann. So gibt es natürlich auch eine Option, damit z.B compiliert, aber nicht assembliert wird. Diese Option heißt -s .
g++ prog.cpp -s
Diese Option wird allerdings fast nie benötigt.
Die Option -E ist allerdings wieder nützlich, mit ihr wird nur der Präprozessor benutzt.
g++ prog.cpp -E
So kann man z.B. sehen, ob mit den Makros alles ordnungsgemäß geklappt hat.
Hier soll auch die Option -ansi nicht unerwähnt werden. Da g++ einige C++ Erweiterungen beinhaltet, die nicht standardkomform sind und mit dem Standard im Konflikt stehen, kann es sein, das sich Programme, die mit g++ compiliert werden, nicht standardkonform verhalten. Um dies zu umgehen gibt es die Option ansi.
g++ prog.cpp -o prog.out -ansi
Dies bewirkt, das diese nicht standardkonformen Erweiterungen nicht berücksichtigt werden, so ist das Programm standerdkonform.
Allerdings gibt es noch weitere nicht standardkonforme Erweiterungen in g++, um gewarnt zu werden - sollten diese benutzt werden - gibt es die Option -pedantic:
g++ prog.cpp -o prog.out -pedantic
Eine andere, sehr nützliche Option ist -O . Mit dieser Option kann man das Programm Optimieren lassen (so das es kleiner ist oder schneller läuft). Nach dem O steht noch eine Zahl von 1-3, die den Grad der Optimierung festlegt. 3 ist am meisten optimiert
g++ prog.cpp -o prog.out -O2
Diese Optimierung bringt aber auch als Nachteil mit sich, dass das compilieren länger dauert.
--etlam 10:00, 12. Aug. 2007 (CEST)
- Zunächst einmal ein wenig Korinthenkackerei zum Anfang :-) Der GCC ist nicht ein Compiler. sondern eine Sammlung von Compilern, wie der Name (GNU Compiler Collection) bereits sagt. In der Sammlung gibt es unter anderem den GNU C Compiler gcc (kleingeschieben) und den GNU C++ Compiler g++ (der hier relevant ist). Ok, strenggenommen ist das nicht ganz richtig, weil gcc und g++ nur die "Compilertreiber" sind, die eigentlichen Compiler heißen cc1 bzw. cc1plus. Assembler unterstützt der GCC aber nicht (außer insofern, als er Assemblercode ausspuckt); wenn man ihm Assemblerdateien vorsetzt, reicht er sie unbesehen an denselben Assembler weiter, den er auch für den generierten Assemblercode verwendet (unter Linux ist das der GNU-Assembler, der unabhängig vom GCC entwickelt und verbreitet wird; auf anderen Systemen kann das auch der Assembler des jeweiligen Betriebssystem-Herstellers sein).
- Das mit der Sammlung von Compilern... habe ich ausgebessert (nur das mit dem cc1plus habe ich rausgelassen, da das meiner Meinung nach etwas zu kompliziert wird für Anfänger...)
- Zu dem Assembler Punkt: Ich dachte das zwar immer anders, glaube dir aber (habe auch etwas nachgeforscht), heißt es also, dass auf Systemen, auf denen (aus welchen Gründen auch immer keinen Assembler gibt) man kein GCC verwenden kann, oder ist der Assembler schon mitgeliefert, aber nicht Teil des Projekts?
- Weiterhin: GPL Steht nicht für GNU Public License, sondern GNU GPL steht für GNU General Public License (das "GNU" vor "GPL" sollte nicht vergessen werden, denn es ist zwar die bekannteste, aber nicht die einzige Lizenz namens GPL = "General Public License").
- Ja, klar ich versteh nicht, wie ich so einen dummen Fehler machen konnte ;)
- Auch ruft g++ nicht gcc auf, sondern cc1plus (den C++-Compiler), den Compiler und den Linker (letzteren oft über ein Wrapper-Programm, das C++-spezifische Aufgaben insbesondere im Zusammenhang mit Templates ausführt, die traditionelle Linker nicht beherrschen). Allerdings sind das alles Details, die man als normaler Anwender nicht wirklich wissen muss; für den Normalanwender reicht die (strenggenommen nicht ganz korrekte) Regel: gcc ist der C-Compiler, g++ der C++-Compiler.
- Ja, also ich würde das eher nicht einbauen, und es dbaei belassen, da es ja sonst für Anfänger vielleicht doch etwas zu kompliziert ist...
- Übrigens ist bei aktuellen GCC-Versionen der Präprozessor in den Compiler integriert.
- Es ist zwar integriert, aber es sind ja noch zwei Arbeitsschritte... Soll ich das dann ändern oder so lassen?
- Ein viel wichtigerer Fehler ist jedoch: Durch die Optimierung können nicht "neue, seltsame Fehler auftauchen" (es sei denn, man stößt auf einen Bug im Compiler), sondern Fehler im Programm, die ohne den Optimierungsschalter bereits im kompilierten Programm vorhanden sind, können durch die Optimierung aufgedeckt werden. Das heißt: Programme, die mit Optimierung fehlerhaftes Verhalten zeigen, sind normalerweise von vorneherein fehlerhaft. Diesen Fehler durch Weglassen der Optimierung zu überdecken, ist keine gute Idee (dass man ihn bei Tests ohne Optimierung nicht festgestellt hat, ist ja kein Beweis, dass er unter keinen Umständen zuschlägt; im schlimmsten Fall erhält man unbemerkt falsche Ergebnisse). Dies ist eine Fehlinformation, die echten Schaden anrichten kann.
- Das leuchtet mir ein, ich habe es auch verbessert.
- Beim Thema Dokumentation des GCC bzw. g++ sollte man die Info-Dateien nicht vergessen (Aufruf:
info gcc
bzw. über den Info-Modus von (X)Emacs). Da steht noch viel mehr drin als in der manpage, aber schön übersichtlich auf mehreren Seiten mit Menüs etc.
- Stimmt, ich habe es eingefügt, nur den teil mit X(Emacs) habe ich noch nicht erwähnt, dass kannst du ja dann hinzufügen (Ich benutze nicht Emacs, kenn mich da also nicht aus).
- Amsonsten kann man den Text m.E. i.W. so lassen (modulo Rechtschreibfehler, versteht sich), wobei allerdings die Frage ist, ob man die Option -s wirklich erwähnen sollte.
- Also ich habe die Option erwähnt, weil dann alles angesprochen wurde, bei dem man den Prozess zwischendurch anhalten kann, außerdem sieht man so, dass es beim GCC wirklich unheimlich viele Optionen gibt.
- Stattdessen sollte man besser die Option -Wall erwähnen, die viele äußerst nützliche Warnungen einschaltet (trotz des Namens schaltet sie aber nicht alle Warnungen an), -W (in neueren Versionen -Wextra) zum Einschalten einiger weiterer Warnungen, die manchmal auch ganz nützlich sein können, die Option -ansi, die spezifische g++-Erweiterungen abschaltet, die mit dem C++-Standard im Konflikt stehen (sprich: ein Programm, das ohne -ansi kompiliert wird, könnte sich in Ausnahmefällen eventuell nicht standardkonform verhalten) und -pedantic, das über einige weitere nicht standardkonforme Erweiterungen warnt (diese betreffen aber keine standardkonformen Programme). Eigentlich sollte man niemals ein Programm ohne -Wall kompilieren, und gerade für Anfänger empfiehlt sich auch ein -pedantic hinzuzufügen. --Ce 14:54, 12. Aug. 2007 (CEST)
- Ich habe alles eingefügt - Wall hatte ich mir sogar noch vorgenommen zu erwähnen und dann vergessen...
- Danke an euch beide für die Vorarbeit. --Prog 17:24, 16. Aug. 2007 (CEST)
mal sone frage...
Bearbeitenähh, dieses nächste kapitel, worum solls da gehen, guis schön und gut, aber was: compiler guis, oder guis für die eigenen programme, oder etwas ganz anderes?
- Es soll um GUIs für die eigenen Programme gehen. Dies kann natürlich nur angerissen werden, da ein einzelnes Kapitel unmöglich eine, geschweige den mehrere GUIs ausführlich behandeln kann. Eine Verlinkung zu anderen Büchern die sich mit diesem Thema beschäftigen ist vorgesehen (sobald es entsprechende gibt). Compiler GUIs (besser IDEs) könnten in diesem Kapitel mit untergebracht werden, wenn das gewünscht wird. --Prog 23:48, 23. Okt. 2007 (CEST)
Was stimmt jetzt?
BearbeitenMir ist gerade beim durchlesen aufgefallen, dass im Kapitel
Bei diesen Warnungen wird der Code zwar kompiliert, aber Sie sollten versuchen, wartungsfreie Programme zu schreiben
und hier in der Diskussion
Bei diesen Warnungen wird der Code zwar kompiliert, aber Sie sollten versuchen, warnungsfreie Programme zu schreiben
steht. Welche Variante ist jetzt die richtige? --Steef389 23:50, 3. Feb. 2008 (CET)
- Es geht darum Programme zu schreiben, die keine Compiler-Warnungen ausgeben. Warnungen sind oft ein Indiz für nicht genaue oder fehleranfällige Codefragmente. -- ThePacker 01:24, 4. Feb. 2008 (CET)
"Open Source"
Bearbeiten„GCC steht unter der GNU General Public License (GNU GPL), das heißt, GCC ist Open Source und jeder ist berechtigt, den Quellcode einzusehen, zu verändern und natürlich auch GCC zu verwenden.“
GCC ist Teil des GNU-Projekts und vertritt damit entsprechend auch die GNU-Philosophie. GCC ist zwar nach Definition der OSI "Open Source", bezeichnet sich selbst aber vehement als "freie Software". Daher sollte fairerweise auch dieser Begriff verwendet werden. "Open Source" verbindet eher mit Raymond als mit Stallman, und das ist im GNU-Kontext einfach nicht angemessen.
Genauso stoßen mir Formulierungen wie „Außerdem gibt es unter Linux noch eine übersichtliche Dokumentation bei info.“ auf. Info kommt nicht von Linux, Info kommt von GNU. Das hat mit dem Kernel nichts, aber auch rein gar nichts zu tun. Info gibt es auch unter GNU/kFreeBSD, GNU/NetBSD, GNU/HURD, in jeder GNU-Variante der Welt, aber eben nicht in jedem Linux der Welt.
--Implementation 18:52, 13. Jun. 2012 (CEST)
- Da kann ich nur zustimmen. Ich werd mal ein wenig dran arbeiten. --Alip2890 18:01, 21. Aug. 2012 (CEST)