namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:translation_units

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:begriffe#C++98]] bis [[kennen:begriffe#C++17]], 
 +(noch) nicht die mit [[kennen:begriffe#C++20]] eingeführten [[.:Module]].
 +===== Organisation =====
 +[[.:begriffe#Modularisierung]] 
 +ist eine Technik zum Aufbrechen und Beherrschen der 
 +[[.:begriffe#Komplexität]] 
 +von Programmieraufgaben.
 +Die Abgrenzung von Programmteilen kann 
 +  * logisch über [[#Namensräume]] und
 +  * physisch durch die Aufteilung in mehrere [[.:begriffe#Quelltext]]-Dateien erfolgen.
 +Inhaltlich zusammengehörige 
 +[[.:typen#Typen|Datentypen]]
 +und [[.:funktion|Funktionen]]
 +lassen sich als [[.:begriffe#Modul]]
 +in einer Quelltextdatei bündeln.
 +Vorspanndateien ([[#Header]]) enthalten 
 +[[.:begriffe#Deklaration|Deklarationen]] und
 +[[.:begriffe#Definition|Definitionen]],
 +z.B. [[.:funktion#Deklaration|Funktionsprototypen]],
 +die zur Nutzung der Moduls notwendig sind.
 +Die Kommunikation mit dem Modul sollte
 +nur über die dadurch festgelegte 
 +[[.:begriffe#Schnittstelle]] erfolgen
 +([[.:begriffe#Geheimnisprinzip]]).
 +
 +Bei der [[#Übersetzung]] entstehende 
 +[[.:begriffe#Objektdatei|Objektdateien]]
 +können mit 
 +[[.:begriffe#Bibliothek|Bibliotheken]]
 +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 | ''*.h,  *.hpp, *.hxx''|
 +| Quelltext   | ''*.cc, *.cpp, *.cxx''|
 +| Objektdatei | ''*.o,  *.obj''|
 +| Bibliothek  | ''lib*.a, lib*.so, *.lib, *.dll''|
 +| Programm    | ''a.out, *.exe''|
 +
 +===== Namensräume =====
 +Namenskonflikte können die Integration von Modulen vereiteln,
 +wenn derselbe Name in ihnen mehrfach definiert wird. Namensräume 
 +(Schlüsselwort [[.:keywords#namespace]])
 +begrenzen die Verschmutzung des globalen Namensraumes.
 +
 +Syntax:
 +
 +>  ''namespace'' Namensraumbezeichner
 +>  ''{''
 +>>  Deklarationen
 +>>  Definitionen
 +>  ''}''
 +
 +Namensbereiche sind schachtelbar.
 +Ein Namensraum darf mehrfach, 
 +auch in verschiedenen Dateien, 
 +geöffnet, erweitert und geschlossen werden.
 +Der Namensraum ''std'' ist jedoch als abgeschlossen zu betrachten.
 +Unbenannte Namensräume kapseln globale Namen,
 +die nur innerhalb eines Moduls sichtbar sein sollen 
 +(ohne externe [[#Bindung]]).
 +Lange Namensraumbezeichner können durch kürzere ersetzt werden:
 +<code cpp>
 +namespace fs = std::filesystem;
 +</code>
 +Namen sind außerhalb ihres Namensraumes 
 +qualifiziert mit dem Namensraumbezeichner anzugeben.
 +Einzelne Namen und ganze Namensräume können 
 +mit der [[.:keywords#using]]-Anweisung
 +in einen Block oder global importiert werden.
 +
 +<code cpp>
 +std::cout << "Hallo" << std::endl;
 +
 +using std::cout;
 +using namespace std;
 +cout << "Hallo" << endl;  // nun ohne std:: nutzbar
 +</code>
 +
 +===== Header =====
 +Modulschnittstellen werden vor der Nutzung 
 +durch Einbinden von Deklarationsdateien (Header) bekannt gemacht.
 +[[.:header|Standard-Header]] werden in spitzen Klammern angegeben.
 +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 <Standardheader>
 +#include "mein_header.h"
 +</code>
 +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 "Include-Wächtern" versehen,
 +deren eindeutige Namen dies durch bedingte Übersetzung verhindern:
 +
 +<code cpp>
 +#ifndef MEIN_HEADER_H
 +#define MEIN_HEADER_H
 +// ... Abhängigkeiten 
 +// ... Deklarationen
 +#endif // MEIN_HEADER
 +</code>
 +Viele Compiler erlauben als Ersatz für den Include-Wächter auch die Nutzung der nicht standardisierten Präpozessoranweisung 
 +''#pragma once''.
 +
 +===== Bindung =====
 +In einer Quelltextdatei definierte Funktionen 
 +und globale Variablen haben interne Bindung,
 +wenn sie mit dem [[.:typen#Spezifizierer]]
 +[[.:keywords#static]]
 +oder in einem namenlosen [[#Namensräume|Namensraum]]
 +[[.:typen#Deklaration|deklariert]] wurden.
 +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 [[.:typen#Spezifizierer]]
 +[[.:keywords#extern]] angemeldet wurden.
 +
 +<code cpp>
 +extern int global;      // modul1.h
 +int minimum(int, int);
 +</code>
 +
 +<code cpp>
 +int global;             // modul1.cpp
 +
 +int minimum(int x, int y) 
 +{
 +  return x<y ? x : y;
 +}
 +</code>
 +
 +<code cpp>
 +#include "modul1.h"
 +
 +int main()              // main.cpp
 +{
 +  global = minimum(0, 1);
 +  return global;
 +}
 +</code>
 +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, Wertrückgabe und Stackbereinigung haben.
 +Da andere Programmiersprachen bestimmte Merkmale von C++ nicht unterstützen, 
 +sind Überladen u.ä. für solche Funktionen nicht nutzbar.
 +
 +<code cpp>
 +extern "C" int minimum(int, int);
 +</code>
 +
 +===== Übersetzung =====
 +<code cpp>
 +<...> \
 +*.h    => Präprozessor => Compiler => *.o  => Linker => Programm
 +*.cpp /                                |        ^
 +                                 Archivar <=> Bibliotheken
 +</code>
 +Ein Programm entsteht in einem mehrstufiger Prozess,
 +auch wenn dieser mit einem einzigen Befehl angestoßen wird.
 +
 +  - Für jede Quelltextdatei ([[.:begriffe#Übersetzungseinheit]]) einzeln (getrennte Übersetzung):
 +    - Vorverarbeiten mit dem [[.:begriffe#Präprozessor]] ''cpp'':
 +      * [[.:cpp#Einbinden von Dateien]] (''#include'' ...),
 +      * [[.:cpp#bedingte Übersetzung]] (''#if'' ... ''#endif'')
 +      * und [[.:cpp#Textersatz]] (''#define'' ...) ausführen. 
 +    -  Übersetzen: Mit dem Ergebnis der Vorverarbeitung wird der [[.:begriffe#Compiler]] gefüttert.\\ Für jeden erfolgreich übersetzten Quelltext entsteht eine gleichnamige Objektdatei.
 +  -  Verbinden: Objektdateien und Bibliotheken werden vom [[.:begriffe#Linker]] zum ausführbaren Programm zusammengeführt.
 +
 +===== Projektverwaltung =====
 +Die Übersetzung und Projektverwaltung erfolgt systemabhängig
 +
 +  * über Kommandozeilenwerkzeuge und Steuerdateien oder 
 +  * in integrierten Entwicklungsumgebungen (z.B. [[http://www.codeblocks.org|Code::Blocks]]).
 +
 +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.
 +[[..:lernen:CMake]] (cross-platform make) geht noch einen Schritt weiter.
 +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
 +</code>
 +Fehlt die Angabe ''-o progname'' (o wie output), 
 +findet sich die ausführbare Datei als ''a.out'' ("Assembler Output").
 +
 +Die Übersetzung einzelner Quelltexte erfolgt mit dem Schalter ''-c'' (compile):
 +
 +<code cpp>
 +g++ -c main.cpp
 +g++ -c modul1.cpp
 +</code>
 +Die entstehenden Objektdateien werden zum Programm zusammengeführt (gelinkt):
 +<code cpp>
 +g++ -o progname main.o modul1.o
 +</code>
 +Erfordert ein Programm bestimmte Bibliotheken 
 +(''lib*.a'' oder ''lib*.so''), 
 +ist beim Linken ''-l name'' anzugeben, 
 +Der ''name'' ist dabei der nach code|lib| stehende Teil des Bibliotheksnamens,
 +z.B. ist ''libm.a'' die Mathematik-Bibliothek.
 +<code cpp>
 +g++ prog.cpp -lm
 +</code>
 +Die Kombination unterschiedlichster Übersetzungsstufen ist erlaubt:
 +<code cpp>
 +g++ -o progname main.cpp modul1.o -lm
 +</code>
 +
 +==== Archivieren in Bibliotheken ====
 +Mit dem Archivar ''ar'' lassen sich Bibliotheken aus Objektdateien zusammenstellen,
 +pflegen und bereinigen. 
 +Die Symboltabelle für den Linker wird mit dem Befehl ''ranlib'' erzeugt.
 +Zur Dokumentation siehe ''man ar'' bzw. ''man ranlib''.
 +
 +==== Automatisieren mit make ====
 +Das Werkzeug ''make'' unterstützt die Automatisierung.
 +Mit einem einfachen Kommando
 +
 +<code cpp>
 +make
 +</code>
 +kann ein Projekt aktualisiert werden. Der Aufruf
 +
 +<code cpp>
 +make test
 +</code>
 +könnte einen Regressionstest (Fehlerprüfung nach Wartung) veranlassen. Mit der Zielangabe
 +<code cpp>
 +make clean
 +</code>
 +könnten Zwischendateien beräumt werden. 
 +Voraussetzung ist eine Datei ''Makefile''
 +im (aktuellen) Projektverzeichnis.
 +Beim Anlegen der Datei ist darauf zu achten, 
 +dass Tabulatoren auch wirklich als Tabs in der Datei gespeichert werden.
 +Im ''Makefile'' werden die verschiedenen Ziele definiert.
 +
 +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 ''make'', alle Voraussetzungen zu erfüllen.
 +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 ''make'' den Aktualisierungsprozess ab.
 +
 +<code cpp>
 +# Kommentar - Beispiel Makefile
 +
 +all :   progname
 +
 +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
 +</code>
 +Der ''make''-Aufruf ohne Parameter führt das oberste Ziel aus.
 +Bei unbekannten Zielen gibt sich ''make'' spröde:
 +
 +<code cpp>
 +make love
 +make: *** No rule to make target 'love'. Stop.
 +</code>
  

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki