www.wikidata.de-de.nina.az
Der C Praprozessor cpp auch C Precompiler ist der Praprozessor der Programmiersprache C In vielen Implementierungen ist er ein eigenstandiges Computerprogramm das durch den Compiler als erster Schritt der Ubersetzung aufgerufen wird Der Praprozessor bearbeitet Anweisungen zum Einfugen von Quelltext include zum Ersetzen von Makros define und bedingter Ubersetzung if Die Sprache der Praprozessor Anweisungen ist nicht spezifisch zur Grammatik der Sprache C Deshalb kann der C Praprozessor auch zur Bearbeitung anderer Dateitypen verwendet werden Inhaltsverzeichnis 1 Hintergrund 2 Der C Praprozessor als Textersetzer 3 Phasen 4 Einschleusen von Dateiinhalten 5 Bedingte Ersetzung 6 Definition und Ersetzung von Makros 6 1 Makro uber mehrere Zeilen 6 2 Makrodefinition zurucknehmen 6 3 Umwandlung eines Makroparameters in eine Zeichenkette 6 4 Verkettung von Makroparametern 6 5 Standardisierte Makros 6 6 Gefahren von Makros 7 Gezielter Abbruch der Ubersetzung 8 Andern des Dateinamens und der Zeilennummern 9 Beeinflussung des Compilers 10 Literatur 11 EinzelnachweiseHintergrund BearbeitenDie Programmiersprache C verfugte in ihren fruhesten Versionen uber keinen Praprozessor Er wurde unter anderem auf Betreiben von Alan Snyder siehe auch Portable C Compiler eingefuhrt vor allem aber um in C das Einfugen anderer Quelltextdateien wie in BCPL einer Vorgangersprache von C zu erlauben und das Ersetzen einfacher parameterloser Makros zu ermoglichen Erweitert von Mike Lesk und John Reiser um parameterbehaftete Makros und Konstrukte zur bedingten Ubersetzung entwickelte er sich im Laufe der Zeit vom optionalen Zusatzprogramm eines Compilers zu einer standardisierten Komponente der Programmiersprache Die von der Kernsprache unabhangige Entwicklung erklart die Diskrepanzen in der Sprachsyntax zwischen C und dem Praprozessor 1 2 In den Anfangsjahren war der Praprozessor ein eigenstandiges Programm das sein Zwischenergebnis an den eigentlichen Compiler ubergab der es dann ubersetzte Heute werden die Praprozessor Anweisungen von den Compilern fur C und C in einem einzigen Arbeitsgang mitberucksichtigt Auf Wunsch kann von ihnen zusatzlich oder ausschliesslich das Resultat ausgegeben werden das ein Praprozessor geliefert hatte Der C Praprozessor als Textersetzer BearbeitenDa sich der C Praprozessor nicht auf die Beschreibung der Sprache C stutzt sondern ausschliesslich seine ihm bekannten Anweisungen erkennt und bearbeitet kann er auch als reiner Textersetzer fur andere Zwecke verwendet werden Beispielsweise wird fur die Kompilierung von Ressource Dateien auch der C Praprozessor verwendet Dieser erlaubt es C Headerdateien einzubetten und ermoglicht somit Werte zum Beispiel mit define definierte Zahlwerte oder Zeichenketten zwischen C Code und Ressource Code zu teilen Wichtig ist dabei dass der Ressource Compiler keinen komplexen C Code verarbeiten kann Der C Code wie Funktions Deklarationen oder Struktur Definitionen kann dabei mit einem if oder ifdef bedingt fur den Ressource Compiler ausgeblendet werden wobei bestimmte Makros vom Ressource Compiler definiert werden RC INVOKED die beim C Compiler nicht definiert sind Dies nutzt auch die Header Datei windows h aus die somit sowohl in Programm Code wie auch in Ressource Code teilweise genutzt werden kann 3 Phasen BearbeitenDer C Standard definiert unter anderem die nachfolgenden vier von insgesamt acht Ubersetzungsphasen Diese vier werden vom C Praprozessor durchgefuhrt Ersetzung von Trigraph Zeichen durch das korrespondierende einzelne Zeichen Zusammenfuhrung von Zeilen die durch den umgekehrten Schragstrich am Zeilenende aufgeteilt wurden gedacht etwa fur lange Zeichenketten bei Lochkarten oder Magnetbandern mit fester Record Lange Ersetzung von Makros und Einschleusen von Dateiinhalten Praprozessor Anweisungen zum Einschleusen von Dateiinhalten zusatzlich zu ubersetzender Quelltext und fur bedingte Ubersetzungen werden ausgefuhrt Gleichzeitig werden Makros expandiert Einschleusen von Dateiinhalten BearbeitenDie haufigste Nutzung des Praprozessors besteht im Einschleusen anderer Dateiinhalte include lt stdio h gt int main void printf Hello world n return 0 Der Praprozessor ersetzt die Zeile include lt stdio h gt mit dem Inhalt der Header Datei stdio h in der unter anderem die Funktion printf deklariert wird Die Datei stdio h ist Bestandteil jeder C Entwicklungsumgebung Die include Anweisung kann auch mit doppelten Anfuhrungszeichen include stdio h verwendet werden Dann wird bei der Suche nach der betroffenen Datei zusatzlich zu den Verzeichnissen des C Compilers auch das aktuelle Verzeichnis im Dateisystem durchsucht Durch Optionen fur den C Compiler der diese wiederum an den C Praprozessor weiterreicht oder durch Aufrufoptionen fur den C Praprozessor kann festgelegt werden in welchen Verzeichnissen nach include Dateien gesucht werden soll Eine allgemein ubliche Konvention legt fest dass include Dateien die Dateinamenserweiterung h erhalten Originare C Quelldateien erhalten die Dateinamenserweiterung c Das ist jedoch nicht zwingend vorgeschrieben Auch Inhalte aus Dateien mit anderer Dateinamenserweiterung als h konnen auf diese Art eingeschleust werden Innerhalb einzuschleusender Dateien wird haufig durch bedingte Ersetzung dafur gesorgt dass Deklarationen fur die nachfolgenden Compiler Phasen nicht mehrfach wirksam werden sofern der Dateiinhalt mehrfach durch include eingeschleust wird Bedingte Ersetzung BearbeitenDie Anweisungen if ifdef ifndef else elif und endif werden fur bedingte Ersetzungen des C Praprozessors verwendet z B ifdef WIN32 include lt windows h gt else include lt unistd h gt endif In diesem Beispiel pruft der C Praprozessor ob ihm ein Makro namens WIN32 bekannt ist Ist das der Fall wird der Dateiinhalt von lt windows h gt eingeschleust ansonsten der von lt unistd h gt Das Makro WIN32 kann implizit durch den Ubersetzer z B durch alle Windows 32 Bit Compiler durch eine Aufrufoption des C Praprozessors oder durch eine Anweisung mittels define bekannt gemacht werden Im folgenden Beispiel wird der Aufruf von printf nur beibehalten sofern das Makro VERBOSE an dieser Stelle einen numerischen Wert von 2 oder mehr aufweist if VERBOSE gt 2 printf Kontrollausgabe n endifDefinition und Ersetzung von Makros BearbeitenIn C sind Makros ohne Parameter mit Parametern und seit C99 auch mit einer variablen Zahl an Parametern zulassig define lt MAKRO NAME OHNE PARAMETER gt lt Ersatztext gt define lt MAKRO NAME MIT PARAMETER gt lt Parameterliste gt lt Ersatztext gt define lt MAKRO NAME MIT VARIABLEN PARAMETERN gt lt optionale feste Parameterliste gt lt Ersatztext gt Bei Makros mit Parametern ist zwischen dem Makronamen und der offnenden runden Klammer kein Leerraum zugelassen Ansonsten wird das Makro inklusive der Parameterliste als reiner Textersatz fur den Makronamen verwendet Zur Unterscheidung von Funktionen bestehen die Namen von Makros ublicherweise ausschliesslich aus Grossbuchstaben guter Programmierstil Eine Ellipse zeigt an dass das Makro an dieser Stelle ein oder mehrere Argumente akzeptiert Auf diese kann im Ersatztext des Makros mit dem speziellen Bezeichner VA ARGS Bezug genommen werden Makros ohne Parameter werden beim Auftreten des Makronamens im Quelltext durch ihren Ersatztext der auch leer sein kann ersetzt Bei Makros mit Parametern geschieht das nur wenn nach dem Makronamen eine Parameterliste folgt die in runde Klammern eingeschlossen ist und in der Parameteranzahl der Deklaration des Makros entspricht Beim Ersetzen von Makros mit variabler Parameterzahl werden die variablen Argumente inklusive der sie trennenden Kommata zu einem einzigen Argument zusammengefasst und im Ersatztext statt VA ARGS eingefugt Makros ohne Parameter werden haufig fur symbolische Namen von Konstanten verwendet define PI 3 14159 Ein Beispiel fur ein Makro mit Parametern ist define CELSIUS ZU FAHRENHEIT t t 1 8 32 Das Makro CELSIUS ZU FAHRENHEIT beschreibt die Umrechnung einer Temperatur angegeben als Parameter t aus der Celsius in die Fahrenheit Skala Auch ein Makro mit Parametern wird im Quelltext ersetzt int fahrenheit celsius 10 fahrenheit CELSIUS ZU FAHRENHEIT celsius 5 wird durch den C Praprozessor ersetzt zu int fahrenheit celsius 10 fahrenheit celsius 5 1 8 32 Makros mit einer variablen Anzahl von Parametern bieten sich an um Argumente an eine variadische Funktion zu ubergeben define MELDUNG fprintf stderr VA ARGS Zum Beispiel wird int i 6 j 9 MELDUNG DEBUG i d j d n i j durch den C Praprozessor ersetzt zu int i 6 j 9 fprintf stderr DEBUG i d j d n i j Da in C aufeinanderfolgende Zeichenkettenliterale wahrend der Ubersetzung zusammengefasst werden ergibt sich hieraus ein gultiger Aufruf der Bibliotheksfunktion fprintf Makro uber mehrere Zeilen Bearbeiten Da in der zweiten Phase des C Praprozessors durch das Zeichen am Zeilenende schon die Zusammenfuhrung auf eine Zeile erfolgt konnen Makros durch diesen Mechanismus auf mehreren Zeilen deklariert werden Makrodefinition zurucknehmen Bearbeiten Eine vorherige Makrodefinition kann mit undef wieder ruckgangig gemacht werden Das dient dazu Makros nur in einem begrenzten Codeabschnitt verfugbar zu machen undef CELSIUS ZU FAHRENHEIT Der Geltungsbereich des Makros endet hier Umwandlung eines Makroparameters in eine Zeichenkette Bearbeiten Wird einem Parameter im Ersatztext eines Makros ein vorangestellt so wird bei der Ersetzung das Argument durch Einschliessen in doppelte Hochkommata in eine Zeichenkette umgewandelt stringized Folgendes Programm gibt string aus nicht hallo include lt stdio h gt define STR X X int main void char string hallo puts STR string return 0 Verkettung von Makroparametern Bearbeiten Der Verkettungsoperator erlaubt es zwei Makroparameter zu einem zu verschmelzen englisch token pasting Das folgende Beispielprogramm gibt die Zahl 234 aus include lt stdio h gt define GLUE X Y X Y int main void printf d n GLUE 2 34 return 0 Die Operatoren und ermoglichen bei geschickter Kombination das halbautomatische Erstellen beziehungsweise Umstellen ganzer Programmteile durch den Praprozessor wahrend der Ubersetzung des Programms was allerdings auch zu schwer durchschaubarem Code fuhren kann 4 Standardisierte Makros Bearbeiten Zwei vordefinierte Makros sind FILE aktueller Dateiname und LINE aktuelle Zeile innerhalb der Datei include lt stdio h gt include lt stdlib h gt define MELDUNG text fprintf stderr Datei s Zeile d s n FILE LINE text int main void MELDUNG Kapitaler Fehler Programmende return EXIT FAILURE Im Fehlerfall wird so vor dem Programmende folgender Text ausgegeben Datei beispiel c Zeile 10 Kapitaler Fehler Programmende Gefahren von Makros Bearbeiten Wichtig ist dass bei der Deklaration von Makros mit Berechnungen jeder Parameter geklammert werden muss damit beim Aufruf des Makros immer das gewunschte Ergebnis erreicht wird Ware im Beispiel der Temperaturumrechnung die Klammerung um den Parameter t im Ersatztext nicht erfolgt so ware als Ersetzung das mathematisch falsche und nicht gewunschte Ergebnis celsius 5 1 8 32 entstanden Bei Makroaufrufen sind Argumente mit den Operatoren und sowie Funktionen und Zuweisungen als Argumente zu vermeiden da diese durch eventuelle Mehrfachauswertung zu unerwunschten Seiteneffekten oder sogar undefiniertem Code fuhren konnen Die Verwendung von Semikolon im Ersatztext als Ende einer C Anweisung oder als Trenner zwischen mehreren im Makroersatz angegebenen C Anweisungen sollte vermieden werden da dies Nebeneffekte auf den weiter zu ubersetzenden Quelltext bewirken kann Makros sind global und lassen sich nicht in Namensraume C Konstrukt einsperren Einmal vergebene Bezeichner durfen weder als lokale Variablen noch als Strukturmember auftauchen da hier der C typische Verdeckungseffekt nicht greift Daher mussen diese fur das gesamte Projekt eineindeutig sein was bei der Namensvergabe zu beachten ist Weniger fehleranfallige Programmierung insbesondere in C vermeidet Makros wo immer das moglich ist Beispielsweise lassen sich symbolische Integer Konstanten in C und C mittels enum festlegen Gleitkomma Konstanten mit constexpr C ab 2011 bedingte Compilierung mit if 0 und kleine Berechnungen mit Inline Funktionen ggf mit Templates Gezielter Abbruch der Ubersetzung BearbeitenMit der Anweisung error kann der Ubersetzungsvorgang abgebrochen und eine Meldung ausgegeben werden include lt limits h gt if CHAR BIT 8 error Dieses Programm unterstutzt nur Plattformen mit 8bit Bytes endifAndern des Dateinamens und der Zeilennummern BearbeitenMittels der Anweisung line ist es moglich aus Sicht des Compilers die Nummer der darauf folgenden Zeile und auch den fur Meldungen verwendeten Namen der aktuellen Quelldatei zu manipulieren Dies hat Auswirkungen auf etwaige nachfolgende Compilermeldungen line 42 Diese Zeile hatte in einer Compilermeldung jetzt die Nummer 42 line 58 scan l In einer Meldung ware dies Zeile 58 der Datei scan l Genutzt wird dieser Mechanismus oft von Codegeneratoren wie beispielsweise lex oder yacc um im erzeugten C Code auf die entsprechende Stelle der Ursprungsdatei zu verweisen Dadurch wird die Fehlersuche stark vereinfacht Beeinflussung des Compilers BearbeitenDie Praprozessoranweisung pragma erlaubt es den Compiler zu beeinflussen Derartige Kommandos sind meist compilerspezifisch einige definiert aber auch der C Standard ab C99 z B include lt fenv h gt pragma STDC FENV ACCESS ON Im Folgenden muss der Compiler davon ausgehen dass das Programm Zugriff auf Status oder Modusregister der Fliesskommaeinheit nimmt Literatur BearbeitenBritish Standards Institute Hrsg The C Standard Incorporating TC1 BS ISO IEC 9899 1999 John Wiley amp Sons 2003 ISBN 0 470 84573 2 Kapitel 6 10 1 bis 6 10 9 C99 Standard ISO IEC 9899 TC3 Draft PDF 3 8 MB auf www open std org englisch Einzelnachweise Bearbeiten Dennis M Ritchie The Development of the C Language Abgerufen am 12 September 2010 englisch Rationale for International Standard Programming Languages C PDF 898 kB S 15 Abschnitt 5 1 1 2 abgerufen am 12 September 2010 englisch msdn microsoft com The C Preprocessor Concatenation Abgerufen am 25 Juli 2014 englisch Abgerufen von https de wikipedia org w index php title C Praprozessor amp oldid 232728002