kennen:translation_units
no way to compare when less than two revisions
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
— | kennen:translation_units [2020-08-30 11:39] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== Übersetzungseinheiten ====== | ||
+ | > Divide et impera. | ||
+ | >> --- Römisches Sprichwort | ||
+ | |||
+ | Hinweis: Diese Seite beschreibt [[kennen: | ||
+ | (noch) nicht die mit [[kennen: | ||
+ | ===== Organisation ===== | ||
+ | [[.: | ||
+ | ist eine Technik zum Aufbrechen und Beherrschen der | ||
+ | [[.: | ||
+ | von Programmieraufgaben. | ||
+ | Die Abgrenzung von Programmteilen kann | ||
+ | * logisch über [[# | ||
+ | * physisch durch die Aufteilung in mehrere [[.: | ||
+ | Inhaltlich zusammengehörige | ||
+ | [[.: | ||
+ | und [[.: | ||
+ | lassen sich als [[.: | ||
+ | in einer Quelltextdatei bündeln. | ||
+ | Vorspanndateien ([[# | ||
+ | [[.: | ||
+ | [[.: | ||
+ | z.B. [[.: | ||
+ | die zur Nutzung der Moduls notwendig sind. | ||
+ | Die Kommunikation mit dem Modul sollte | ||
+ | nur über die dadurch festgelegte | ||
+ | [[.: | ||
+ | ([[.: | ||
+ | |||
+ | Bei der [[# | ||
+ | [[.: | ||
+ | können mit | ||
+ | [[.: | ||
+ | zum ausführbaren Programm (Binärdatei) zusammengeführt werden. | ||
+ | Das Modul kann als Objektdatei oder als Bibliothek | ||
+ | weitergegeben und in mehrere Programme eingebunden werden, | ||
+ | ohne geändert oder neu übersetzt werden zu müssen. | ||
+ | Bibliotheken sind Sammlungen von Objektdateien, | ||
+ | die mit einem Bibliothekar oder Archivar genannten Programm | ||
+ | zusammengestellt und gepflegt werden. | ||
+ | Auf der Ebene der Objektdateien und Bibliotheken sind Programmteile | ||
+ | aus unterschiedlichen Programmiersprachen kombinierbar. | ||
+ | |||
+ | Die Dateinamen besitzen je nach System typische Endungen: | ||
+ | |||
+ | | Headerdatei | '' | ||
+ | | Quelltext | ||
+ | | Objektdatei | '' | ||
+ | | Bibliothek | ||
+ | | Programm | ||
+ | |||
+ | ===== Namensräume ===== | ||
+ | Namenskonflikte können die Integration von Modulen vereiteln, | ||
+ | wenn derselbe Name in ihnen mehrfach definiert wird. Namensräume | ||
+ | (Schlüsselwort [[.: | ||
+ | begrenzen die Verschmutzung des globalen Namensraumes. | ||
+ | |||
+ | Syntax: | ||
+ | |||
+ | > '' | ||
+ | > '' | ||
+ | >> | ||
+ | >> | ||
+ | > '' | ||
+ | |||
+ | Namensbereiche sind schachtelbar. | ||
+ | Ein Namensraum darf mehrfach, | ||
+ | auch in verschiedenen Dateien, | ||
+ | geöffnet, erweitert und geschlossen werden. | ||
+ | Der Namensraum '' | ||
+ | Unbenannte Namensräume kapseln globale Namen, | ||
+ | die nur innerhalb eines Moduls sichtbar sein sollen | ||
+ | (ohne externe [[# | ||
+ | Lange Namensraumbezeichner können durch kürzere ersetzt werden: | ||
+ | <code cpp> | ||
+ | namespace fs = std:: | ||
+ | </ | ||
+ | Namen sind außerhalb ihres Namensraumes | ||
+ | qualifiziert mit dem Namensraumbezeichner anzugeben. | ||
+ | Einzelne Namen und ganze Namensräume können | ||
+ | mit der [[.: | ||
+ | in einen Block oder global importiert werden. | ||
+ | |||
+ | <code cpp> | ||
+ | std::cout << " | ||
+ | |||
+ | using std::cout; | ||
+ | using namespace std; | ||
+ | cout << " | ||
+ | </ | ||
+ | |||
+ | ===== Header ===== | ||
+ | Modulschnittstellen werden vor der Nutzung | ||
+ | durch Einbinden von Deklarationsdateien (Header) bekannt gemacht. | ||
+ | [[.: | ||
+ | Eigene Header in Gänsefüßchen werden zuerst bei den Quelltexten | ||
+ | (im aktuellen Projekt-Verzeichnis) gesucht, | ||
+ | danach in den Standard-Include-Verzeichnissen. | ||
+ | |||
+ | <code cpp> | ||
+ | #include < | ||
+ | #include " | ||
+ | </ | ||
+ | Syntaktisch korrekte Header können in beliebiger Folge angegeben werden. | ||
+ | Abhängigkeiten zwischen den Headern sollten in den Headern geregelt werden. | ||
+ | Erfordern Deklarationen eines Headers die Kenntnis anderer Schnittstellen, | ||
+ | muss dieser die anderen Header einbinden. | ||
+ | Eventuelles mehrfaches Einbinden soll nicht zu Übersetzungsfehlern führen. | ||
+ | Header werden deshalb mit " | ||
+ | deren eindeutige Namen dies durch bedingte Übersetzung verhindern: | ||
+ | |||
+ | <code cpp> | ||
+ | #ifndef MEIN_HEADER_H | ||
+ | #define MEIN_HEADER_H | ||
+ | // ... Abhängigkeiten | ||
+ | // ... Deklarationen | ||
+ | #endif // MEIN_HEADER | ||
+ | </ | ||
+ | Viele Compiler erlauben als Ersatz für den Include-Wächter auch die Nutzung der nicht standardisierten Präpozessoranweisung | ||
+ | ''# | ||
+ | |||
+ | ===== Bindung ===== | ||
+ | In einer Quelltextdatei definierte Funktionen | ||
+ | und globale Variablen haben interne Bindung, | ||
+ | wenn sie mit dem [[.: | ||
+ | [[.: | ||
+ | oder in einem namenlosen [[# | ||
+ | [[.: | ||
+ | Auf Bezeichner mit interner Bindung kann nur innerhalb dieses | ||
+ | Quelltextes Bezug genommen werden. | ||
+ | Definierte gleichnamige Bezeichner mit interner Bindung | ||
+ | existieren in verschiedenen Übersetzungseinheiten unabhängig voneinander. | ||
+ | |||
+ | Alle anderen Funktionen und globalen Variablen haben externe Bindung. | ||
+ | Sie dürfen im Programm nur ein einziges Mal definiert sein | ||
+ | (one definition rule). | ||
+ | Funktionen mit externer Bindung können aus anderen Quelltexten heraus aufgerufen werden. | ||
+ | Lediglich ihr Prototyp muss zum Aufruf bekannt sein. | ||
+ | In anderen Dateien definierte globale Variablen mit externer Bindung | ||
+ | sind nutzbar, nachdem sie mit dem [[.: | ||
+ | [[.: | ||
+ | |||
+ | <code cpp> | ||
+ | extern int global; | ||
+ | int minimum(int, | ||
+ | </ | ||
+ | |||
+ | <code cpp> | ||
+ | int global; | ||
+ | |||
+ | int minimum(int x, int y) | ||
+ | { | ||
+ | return x<y ? x : y; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code cpp> | ||
+ | #include " | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | global = minimum(0, 1); | ||
+ | return global; | ||
+ | } | ||
+ | </ | ||
+ | Anmerkung: Im allgemeinen sollten globale Variablen vermieden werden. | ||
+ | Sie stellen ein Problem bei der Wartung | ||
+ | und bei der Parallelisierung von Programmen dar. | ||
+ | |||
+ | Sollen Funktionen aus / in anderen Programmiersprachen aufgerufen werden, | ||
+ | muss der Compiler darauf vorbereitet werden, | ||
+ | weil unterschiedliche Sprachen unterschiedliche Konventionen | ||
+ | der Parameterübergabe, | ||
+ | Da andere Programmiersprachen bestimmte Merkmale von C++ nicht unterstützen, | ||
+ | sind Überladen u.ä. für solche Funktionen nicht nutzbar. | ||
+ | |||
+ | <code cpp> | ||
+ | extern " | ||
+ | </ | ||
+ | |||
+ | ===== Übersetzung ===== | ||
+ | <code cpp> | ||
+ | <...> \ | ||
+ | *.h => Präprozessor => Compiler => *.o => Linker => Programm | ||
+ | *.cpp / | ^ | ||
+ | | ||
+ | </ | ||
+ | Ein Programm entsteht in einem mehrstufiger Prozess, | ||
+ | auch wenn dieser mit einem einzigen Befehl angestoßen wird. | ||
+ | |||
+ | - Für jede Quelltextdatei ([[.: | ||
+ | - Vorverarbeiten mit dem [[.: | ||
+ | * [[.: | ||
+ | * [[.: | ||
+ | * und [[.: | ||
+ | - Übersetzen: | ||
+ | - Verbinden: Objektdateien und Bibliotheken werden vom [[.: | ||
+ | |||
+ | ===== Projektverwaltung ===== | ||
+ | Die Übersetzung und Projektverwaltung erfolgt systemabhängig | ||
+ | |||
+ | * über Kommandozeilenwerkzeuge und Steuerdateien oder | ||
+ | * in integrierten Entwicklungsumgebungen (z.B. [[http:// | ||
+ | |||
+ | Integrierte Entwicklungsumgebungen sind Arbeitswerkzeuge, | ||
+ | die den Programmierer bei der Erstellung von Quelltexten und Programmen, | ||
+ | bei der Fehlersuche und Dokumentation unterstützen (können), | ||
+ | wenn man weiß, wie. | ||
+ | Jede Entwicklungsumgebung wird anders bedient. | ||
+ | Die Beschreibung einzelner Entwicklungsumgebungen erfolgt hier nicht. | ||
+ | Zudem erfordern Entwicklungsumgebungen zumeist die Anwesenheit eines | ||
+ | Tastatur und Maus bedienenden Programmierers. | ||
+ | Mausklicks sind schwer automatisierbar. | ||
+ | |||
+ | Dagegen können Kommandozeilenbefehle leicht in Skripte gefasst | ||
+ | und automatisiert werden. GNU-Werkzeuge g++ und make dienen hier als Beispiel. | ||
+ | [[..: | ||
+ | Es konfiguriert Projekte für die gängigen Compiler auf verschiedenen Systemen. | ||
+ | ==== Übersetzen an der Kommandozeile ==== | ||
+ | Ein Programm aus 2 Quelltexten wird erstellt: | ||
+ | |||
+ | <code cpp> | ||
+ | g++ -o progname main.cpp modul1.cpp | ||
+ | </ | ||
+ | Fehlt die Angabe '' | ||
+ | findet sich die ausführbare Datei als '' | ||
+ | |||
+ | Die Übersetzung einzelner Quelltexte erfolgt mit dem Schalter '' | ||
+ | |||
+ | <code cpp> | ||
+ | g++ -c main.cpp | ||
+ | g++ -c modul1.cpp | ||
+ | </ | ||
+ | Die entstehenden Objektdateien werden zum Programm zusammengeführt (gelinkt): | ||
+ | <code cpp> | ||
+ | g++ -o progname main.o modul1.o | ||
+ | </ | ||
+ | Erfordert ein Programm bestimmte Bibliotheken | ||
+ | ('' | ||
+ | ist beim Linken '' | ||
+ | Der '' | ||
+ | z.B. ist '' | ||
+ | <code cpp> | ||
+ | g++ prog.cpp -lm | ||
+ | </ | ||
+ | Die Kombination unterschiedlichster Übersetzungsstufen ist erlaubt: | ||
+ | <code cpp> | ||
+ | g++ -o progname main.cpp modul1.o -lm | ||
+ | </ | ||
+ | |||
+ | ==== Archivieren in Bibliotheken ==== | ||
+ | Mit dem Archivar '' | ||
+ | pflegen und bereinigen. | ||
+ | Die Symboltabelle für den Linker wird mit dem Befehl '' | ||
+ | Zur Dokumentation siehe '' | ||
+ | |||
+ | ==== Automatisieren mit make ==== | ||
+ | Das Werkzeug '' | ||
+ | Mit einem einfachen Kommando | ||
+ | |||
+ | <code cpp> | ||
+ | make | ||
+ | </ | ||
+ | kann ein Projekt aktualisiert werden. Der Aufruf | ||
+ | |||
+ | <code cpp> | ||
+ | make test | ||
+ | </ | ||
+ | könnte einen Regressionstest (Fehlerprüfung nach Wartung) veranlassen. Mit der Zielangabe | ||
+ | <code cpp> | ||
+ | make clean | ||
+ | </ | ||
+ | könnten Zwischendateien beräumt werden. | ||
+ | Voraussetzung ist eine Datei '' | ||
+ | im (aktuellen) Projektverzeichnis. | ||
+ | Beim Anlegen der Datei ist darauf zu achten, | ||
+ | dass Tabulatoren auch wirklich als Tabs in der Datei gespeichert werden. | ||
+ | Im '' | ||
+ | |||
+ | Syntax: | ||
+ | |||
+ | > Ziel : Tabulator Voraussetzung | ||
+ | > Tabulator Befehl | ||
+ | |||
+ | Zu jedem Ziel wird angegeben, | ||
+ | welche Voraussetzungen oder Abhängigkeiten erfüllt sein müssen, | ||
+ | um die nachfolgenden Befehle ausführen zu können. | ||
+ | |||
+ | Zuerst versucht '' | ||
+ | Voraussetzungen sind Teilziele oder Dateien. | ||
+ | Ist eine Ausgangsdatei jünger als die Zieldatei, | ||
+ | müssen die zu dem Ziel angegebenen Befehle ausgeführt werden. | ||
+ | Bei aktuellen Dateien unterbleibt die Ausführung der Befehle, | ||
+ | und das Ziel gilt als erfüllt. | ||
+ | Tritt irgendwo ein Fehler auf, bricht '' | ||
+ | |||
+ | <code cpp> | ||
+ | # Kommentar - Beispiel Makefile | ||
+ | |||
+ | all : | ||
+ | |||
+ | progname : main.o modul1.o | ||
+ | g++ -o progname main.o modul1.o | ||
+ | |||
+ | main.o : main.cpp | ||
+ | g++ -c main.cpp | ||
+ | |||
+ | modul1.o : modul1.cpp | ||
+ | g++ -c modul1.cpp | ||
+ | |||
+ | # Regressionstest | ||
+ | test : progname input.txt soll.txt | ||
+ | progname < input.txt > output.txt | ||
+ | diff output.txt soll.txt | ||
+ | |||
+ | # Saubermachen | ||
+ | clean : | ||
+ | rm *.o output.txt | ||
+ | </ | ||
+ | Der '' | ||
+ | Bei unbekannten Zielen gibt sich '' | ||
+ | |||
+ | <code cpp> | ||
+ | make love | ||
+ | make: *** No rule to make target ' | ||
+ | </ | ||
kennen/translation_units.txt · Zuletzt geändert: 2020-08-30 11:39 von 127.0.0.1