Inhaltsverzeichnis
C-Präprozessor
Wie immer, sollte man Makro-Zaubertricks vermeiden.— Bjarne Stroustrup [C++ 3. Aufl., S. 214]
Der C-Präprozessor cpp ist ein beim
Übersetzungsprozess
vorgeschaltetes Programm.
Er ersetzt Makros,
sorgt für bedingte Übersetzung
und kann Dateien einbinden.
Er wird von Zeilen gesteuert,
die mit dem Doppelkreuz #
beginnen.
Die Syntax dieser Zeilen hat mit C++ nur sehr wenig zu tun.
Textersatz
Makros
Makros sind benannte "Textbausteine".
Syntax:
#define
Bezeichner Zeichenfolge
#define MfG "Mit freundlichem Gruss" #define PI 3.1415926535
Makrofunktionen
Makros mit Klammern haben mindestens einen Parameter. Für die Parameter darf beim Aufruf beliebiger Text stehen. Dieser Text wird sooft in die Zeichenfolge hineinkopiert, wie der Makroparameter in der Zeichenfolge erscheint.
Syntax:
#define
Bezeichner(
Bezeichnerliste)
Zeichenfolge
#define sqr(x) x*x
Sobald ein definierter Makroname im Quelltext (außerhalb von Zeichenketten) verwendet wird, wird er durch den Text des Makros ersetzt:
double pi2 = sqr(PI);
wird zu
double pi2 = 3.1415926535*3.1415926535;
Gefahren
Da es sich um reinen Textersatz handelt, werden weder Typprüfungen vorgenommen noch Operatorrangregeln beachtet. Ungenügende Klammerung in der Makrozeichenfolge führt zu unerwarteten Ergebnissen:
int x2 = sqr(1+2); // 1+2*1+2 = 5 statt 9
Konstantenvereinbarungen und inline-Funktionen ersetzen in C++ Makros in vielen Fällen. Sie bieten ähnliche Funktionalität bei erhöhter Sicherheit.
Makrodefinitionen löschen
Makrodefinitionen lassen sich rückgängig machen.
Es ist kein Fehler, #undef
auf einen unbekannten Namen anzuwenden.
Syntax:
#undef
Bezeichner
#undef PI
Vordefinierte Makros
Einige Bezeichner sind beim Übersetzen stets vordefiniert und dürfen nicht geändert oder gelöscht werden:
__LINE__ __FILE__ __DATE__ __TIME__
Bedingte Übersetzung
Mit #if
lässt sich steuern,
ob die folgenden Quelltextzeilen übersetzt werden sollen.
#elif
(else if)- und #else
-Anweisungen sind optional,
#endif
muss immer am Schluss stehen.
Die Bedingung muss ein Ausdruck sein,
der bei der Übersetzung als 0 (falsch) oder
verschieden von 0 (wahr) ausgewertet wird.
Syntax:
#if
Bedingung
#elif
Bedingung
#else
#endif
#if defined(unix) // ... Unix-spezifischer Code #else // ... anderes Betriebssystem #endif
Die Schreibweisen
#ifdef
Bezeichner
#ifndef
Bezeichner
sind gleichbedeutend mit
#if defined(
Bezeichner)
#if !defined(
Bezeichner)
Headerdateien enthalten üblicherweise eine "Include-Wächter", der mehrfaches Einbinden unschädlich macht.
#ifndef EINDEUTIGER_BEZEICHNER #define EINDEUTIGER_BEZEICHNER // ... Deklarationen und Typdefinitionen #endif
Fehlermeldungen
Der Übersetzungsprozess lässt sich bei Bedarf mit einer Fehlermeldung stoppen
Syntax:
#error
Fehlermeldung
#error bis hierher und nicht weiter
Dateien einbinden
Fast alle Programme müssen bestimmte Headerdateien einbinden. Zum Compiler-System gehörende Standard-Headernamen werden in spitze Klammern, eigene Vorspanndateien in doppelten Anführungszeichen eingeschlossen. Die eigenen Vorspanndateien werden in dem Verzeichnis (oder den Verzeichnissen) erwartet, wo auch die anderen Quelltexte stehen; dem Übersetzer können andernfalls entsprechende Suchpfade mitgeteilt werden. Das Einbinden ist nicht auf Header beschränkt, jedoch der häufigste Einsatzfall.
Syntax:
#include
Datei
#include <iostream> #include "meinedatei.h"
Dateien dürfen sich nicht gegenseitig einbinden (#include
-Rekursion).