|
|
Copyright (C) 2001-2005 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the copyright holders.
Letzte �nderung 2005-01-01. Basierend auf der englischen Version von 2005-01-01.
Vorwort des �bersetzers: Dieses Dokument enth�lt die �bersetzung der “GNU Pascal Coding Standards”. Einige Worte werden so beibehalten, wie sie im Englischen geschrieben wurden, weil es meiner Meinung nach die Lesbarkeit des Textes f�rdert. F�r Fehler in der �bersetzung bin ich verantwortlich, nicht die urspr�nglichen Autoren. F�r R�ckfragen zur �bersetzung bin ich erreichbar unter: Eike Lange eike@g-n-u.de. Mein besonderer Dank gilt Roland Goretzki f�r seine unerm�dliche Arbeit, dieses Dokument vom Fehlerteufel zu befreien.
Trotz aller Sorgfalt lassen sich Fehler in der �bersetzung nicht ganz ausschlie�en. In Konfliktf�llen gilt stets das englische Original. Bitte teilen sie uns eventuelle Diskrepanzen mit, damit wir sie beheben k�nnen.
Die GNU Pascal Coding Standards wurden von einer Gruppe freiwilliger Helfer des GNU Pascal Projektes entwickelt. Das Ziel dieses Dokumentes ist es, die GNU Coding Standards um spezifische Informationen f�r Pascal-Programmierer zu erg�nzen. Die Informationen in den GNU Coding Standard beziehen sich zu gro�en Teilen auf die Programmiersprache C. Gleichsam erkl�ren sie jedoch viele der Regeln und Prinzipien, die zum Schreiben portabler, robuster und zuverl�ssiger Programme n�tzlich sind. Die meisten dieser Regeln k�nnen mit wenigen Anmerkungen versehen aus dem Dokument �bernommen werden, weswegen sich Referenzen zu den GNU Coding Standards in diesem Dokument befinden.
Letzte Aktualisierung dieses Dokuments (original): 2005-01-01.
Die GNU Pascal Coding Standards sind als Teil der GPC-Distributionen erh�ltlich – in Bin�rdistributionen als Info-Dateien, in Quelltext-Distributions auch als Texinfo-Dateien, aus denen sich weitere Formate wie HTML, PostScript und PDF erzeugen lassen. Eine HTML-Version befindet sich auch auf der Homepage von GPC, http://www.gnu-pascal.de.
Berichtigungen oder Vorschl�ge zu diesem Dokument k�nnen Sie direkt beim Autor einreichen: eike@g-n-u.de. F�r das englischsprachige Original wenden Sie sich bitte an die Dokumentations-Mailingliste des GNU Pascal Compilers, gpc-doc@gnu.de. Da unsere Zeit begrenzt ist, sollten Ihre Vorschl�ge den ge�nderten Text enthalten. Ein “context diff” der Quelldatei im Texinfo-Format ist sehr willkommen, wobei wir einer einfachen Mail auch nicht abgeneigt sind.
Die folgenden Leute sind die Tyrannen, die ihre Art der Programmierung anderen auferlegen: Peter Gerwinski peter(at)gerwinski.de, Frank Heckenbach frank(at)pascal.gnu.de, Markus Gerwinski markus(at)gerwinski.de, Dominik Freche dominik.freche(at)gmx.net, Nicola Girardi nicola(at)g-n-u.de.
Dieses Kapitel der GNU Coding Standards beschreibt unter anderem, wie man sich versichert, da� GNU Software rechtliche Schwierigkeiten vermeidet. Siehe Intellectual Property (standards).
Dieses Kapitel besch�ftigt sich mit einigen grundlegenden Themen zur Gestaltung eines Programmes.
Wir unterst�tzen die Idee, da� die Vielfalt der Programmiersprachen etwas Gutes ist. Verschiedene Programmiersprachen sind n�tzlich f�r verschiedene Aufgaben. Anders als die GNU Coding Standards (see Source Language (standards)) wollen wir Sie nicht davon �berzeugen, da� Sie C oder Pascal oder eine andere einzelne Programmiersprache f�r alles nutzen sollten.
Wenn Sie das lesen, dann haben Sie sich m�glicherweise schon bei einigen Projekten f�r Pascal entschieden oder ziehen dies in Erw�gung. Dieses Dokument will Ihnen Vorschl�ge unterbreiten, wie Sie ihren Quellcode formatieren, wenn Sie in GNU Pascal programmieren.
Sie k�nnen eine C-Bibliothek oder eine C-Objektcode-Datei mit Ihrem Pascal-Programm oder ihrer Unit verlinken. Bitte beachten Sie die Hinweise im GPC-Handbuch bzgl. der Einzelheiten (see Other Languages (gpc)).
Wir empfehlen die Verwendung von in C geschriebenen “Wrapper-Funktionen” zum Zugriff auf C-Bibliotheken, also kleinen Funktionen, die i.w. nichts anderes machen, als die Funktionen der C-Bilbiothek aufzurufen. Der Grund daf�r ist die Portabilit�t. Eines Tages k�nnte es �nderungen an der zu linkenden Bibliothek geben, die direkte external-Deklarationen gef�hrden. Sie sollten dann die Wrapper anpassen, so da� Pascal Programme mit jeder Version dieser Bibliothek zusammenarbeiten.
Bei der Arbeit mit gro�en Paketen kann es passieren, da� die Kompatibilit�t zwischen Versionen einer Library und dem Programm nicht einfach aufrechterhalten werden kann. In diesem Fall kann man direkt zur Bibliothek linken, mit der man arbeiten m�chte, und bindet ebenso eine erg�nzende Datei hinzu, die ausschlie�lich der Versionskontrolle dient. Hier ein Beispiel:
#include <foo.h>
#if FOO_MAJOR != 1 || FOO_MINOR != 2
#error The GPC interface for libfoo was only written for libfoo-1.2.
#error Please get libfoo-1.2 or check for a version of the GPC interface
#error matching your version of libfoo.
#endif
Beachten Sie die Benutzung von != anstelle von < oder >, um eine sehr pr�zise Versionskontrolle durchzuf�hren. Bitte beachten Sie auch, da� dieses Verfahren nur dann anwendbar ist, wenn es nur eine einzige Implementation dieser Bibliothek gibt, d.h. es l��t sich mit einer Bibliothek wie GTK, aber nicht mit libc, libm, curses etc. anwenden.
Ein automatischer Header-�bersetzer ist geplant. Dieses Werkzeug w�rde das Schreiben von Wrapperfunktionen �berfl�ssig machen. Das Schreiben eines solchen Programmes ist eine schwierige Aufgabe, und niemand ist sich wirklich sicher, ob sie �berhaupt durchf�hrbar ist. Wann ein solches Programm verf�gbar sein wird, ist ungewi�.
Sie k�nnen annehmen, da� der GNU C Compiler benutzt wird, um die Wrapper, und, allgemein, jedes bi�chen C-Code zu �bersetzen, das Sie Ihrem Programm hinzuf�gen. Der Grund f�r diese Annahme ist, da� nur der GNU C Compiler garantiert, da� alle Konventionen kompatibel zum GNU Pascal Compiler sind, und das auf jeder Plattform! Der GNU C Compiler und der GNU Pascal Compiler teilen sich dasselbe Backend. Au�erdem wird der GNU C Compiler immer zusammen mit dem GNU Pascal Compiler erzeugt. Damit ist gcc �berall dort vorhanden, wo auch gpc installiert ist.
GNU Pascal hat viele M�glichkeiten, die Standard Pascal nicht bietet. Ob diese M�glichkeiten in einem Programm genutzt werden sollen, ist eine zu h�ufig diskutierte Frage.
Auf der einen Seite kann das Benutzen dieser M�glichkeiten zu effizienteren oder �bersichtlicheren Programmen f�hren. Auf der anderen Seite ist dadurch nur der GNU Pascal Compiler in der Lage, diesen Quelltext zu bearbeiten. Dadurch wird das Kompilieren des Programmes auf Systemen unm�glich, auf denen dieser Compiler nicht vorhanden ist.
Im allgemeinen ist es das beste, Kompatibilit�t zu anderen Compilern oder zum Sprachstandard beizubehalten, wenn diese Kompatibilit�t einfach zu erhalten ist. Leider ist dies jedoch oftmals mit erheblichen Nachteilen verbunden. Als Beispiel dienen viele eingef�gte {$ifdef}s, um alle nicht-Standard-Compiler zu versorgen, was den Code schwerer zu lesen, schreiben, testen und warten macht. Au�erdem sind {$ifdef}s selbst nicht standardisiert. Sie gewinnen also nicht viel.
Daher schlagen wir vor, sich nicht zu sehr an Fragen der Kompatibilit�t st�ren. Alles am GNU Pascal Compiler ist offen (Compiler und Laufzeit-System). Das bedeutet, da� das gesamte Interface bei Bedarf f�r andere Compiler verf�gbar gemacht werden kann. Dazu k�nnen sogar einfach die Quelltexte �bernommen werden, solange die Lizenzvereinbarung erhalten bleibt. Hier erfahren Sie mehr �ber die GNU General Public License: http://www.gnu.org/copyleft/gpl.html. Das ist sinnvoller als eine Zerst�ckelung des Codes. Ein (begrenztes) Beispiel dieser Strategie kann in der gpc-bp-Unit (f�r Borland Pascal) gefunden werden. Schauen Sie einfach in das Interface. Es ist meistens einfach, diese Unit um zus�tzliche Features zu erweitern.
Bitte benutzen Sie die folgenden Features nicht, speziell solche nicht, die lediglich aus Gr�nden der R�ckw�rtskompatibilit�t eingef�hrt wurden:
Str (Foo, s);
s := 'Hallo ' + s;
FillChar (s, SizeOf (s), 0);
um einen String zu leeren ist falsch in GNU Pascal und au�erdem ineffizient, sogar in Borland Pascal. Bitte benutzen Sie folgendes:
s := '';
Dieses Beispiel �ndert lediglich das L�ngenfeld des Strings s, und leert ihn schon dadurch.
Die GNU Coding Standards haben interessante Anmerkungen zu diesem Thema. Siehe Using Extensions (standards).
Dieses Kapitel der GNU Coding Standards beschreibt Konventionen zum Schreiben stabiler Programme. Au�erdem gibt es Richtlinien zur Ausgabe von Fehlermeldungen, zum Kommandozeilen-Interface und dazu, wie sich Bibliotheken verhalten sollten. Bitte lesen Sie auch den entsprechenden Abschnitt der GNU Coding Standards. Siehe Program Behavior (standards).
Einige Hinweise zur Pascal Programmierung:
Die in den GNU Coding Standards besprochene Auswahl zwischen verschiedenen Signal-Funktionen wurde bereits im Run Time System getroffen, so da� Sie sich nicht mehr darum k�mmern m�ssen.
Ein weiterer Unterschied zu den GNU Coding Standards ist das Verhalten bei Fehlerabfragen, die einen “unm�glichen” Zustand entdecken. Wir empfehlen, das Programm nicht einfach abzubrechen. Dies w�rde implizieren, da� der Anwender ein Programmierer ist, der den Fehler schon irgendwie findet. Diese Annahme ist nicht realistisch! Unser Vorschlag ist es deswegen, eine Fehlermeldung herauszugeben, die es dem Anwender erm�glicht, eine Fehlerbeschreibung an die Programmierer zu senden.
Die GNU Coding Standards schlagen au�erdem vor, jeden Funktionsaufruf auf Fehlerr�ckgaben zu �berpr�fen. Dieser Vorschlag pa�t durchaus zu C, jedoch nicht unbedingt zu Pascal. In Pascal wird das Abfangen von Fehlern oftmals automatisch durchgef�hrt, somit brauchen Sie sich in vielen F�llen nicht darum zu k�mmern. Viele I/O-Routinen geben Ihnen nicht einmal einen R�ckgabewert (beispielsweise Reset). Diejenigen Fehlerwerte, die zur�ckgegeben werden, sollten aber auch �berpr�ft werden.
Sie k�nnen die automatischen Fehlerabfragen ausschalten und sich selber darum k�mmern. Tats�chlich ist es so, da� manche Fehler das Programm mit einer Nachricht abbrechen lassen. Speziell in Units oder Modulen wollen Sie stattdessen vielleicht den Benutzern eine M�glichkeit einr�umen, die Ursache des Fehlers zu beheben. Um das zu tun, benutzen Sie bitte den Compiler-Switch {$I-} und testen Sie den Wert der Funktion IOResult (see IOResult (gpc)) oder der globalen Fehlervariablen wie InOutRes (see InOutRes (gpc)). Beachten Sie bitte, da� I/O-Routinen sofort zur�ckkehren, w�hrend InOutRes gesetzt ist, so da� es nicht notwendig ist, nach jeder Operation diesen Wert abzufragen. Folgendes wird dadurch m�glich:
{$local I-}
Rewrite (f, 'bla');
WriteLn (f, 'foo');
WriteLn (f, 'bar');
WriteLn (f, 'baz');
Close (f);
{$endlocal}
if InOutRes <> 0 then
begin
WriteLn (StdErr, GetIOErrorMessage);
...
end;
Es kann jedoch n�tzlich sein, nach Rewrite und anderen Aufrufe zum �ffnen auf Fehler zu testen, denn dort treten die meisten Fehler auf, und ein Test macht andere, nachgestellte Aufrufe oftmals unn�tig.
Die GPC-Unit enth�lt eine Menge Routinen f�r den Umgang mit Tempor�rdateien, Konfigurationsdateien und vielen anderen dateinamenbezogenen Aufgaben. Der Vorteil beim Gebrauch dieser Routinen liegt darin, da� sie unter verschiedenen Betriebssystemen laufen (zum Beispiel DOS und Unix) und da� evtl. dateinamenbezogene Probleme an einer zentralen Stelle (dem Run Time System) behoben werden k�nnen. Das ist besser, als verschiedene Stellen im Code entsprechend anzupassen.
Soweit es die Bibliotheken betrifft, raten wir davon ab, jede einzelne Routine in einer einzigen Datei unterzubringen. Wir hoffen, da� der GNU Pascal Compiler das eines Tages auf der Ebene des Linkers selber macht. Gegenw�rtig, so glauben wir, ist Programmiererfreundlichkeit sinnvoller als die Gr��e der ausf�hrbaren Datei. Au�erdem empfehlen wir, auf Namens-Pr�fixe zu verzichten. Namenskonflikte k�nnen stattdessen durch qualifizierte Bezeichner (UnitName.RoutinenName) gel�st werden.
Dieses Kapitel gibt Ihnen Ratschl�ge, wie Sie Ihre Quelltexte gestalten sollten. Diese Regeln gelten eigentlich nur f�r ver�ffentlichten Code. Wenn Sie als Beispiel Kommentare in der alten Form (* this one *) schreiben m�chten, so geht das nat�rlich vor�bergehend, bei der Ver�ffentlichung sollten Sie dann allerdings unsere diesbez�glichen Ratschl�ge beherzigen. Da man aber niemals wissen kann, ob und wann man den Code ver�ffentlicht, ist es vorzuziehen, sich von vornherein an diese Ratschl�ge zu halten.
Pascal Quelldateien sollten die Endung .pas haben. Der Dateiname ohne diese Endung sollte der Name des Programmes, der Unit oder des Modules sein, aber kleingeschrieben. Es sollte nur eine einzige Unit, ein einziges Programm oder Modul pro Datei geben.
Der Code sollte mit der Option -Wall, sowohl mit als auch ohne -O3 kompilierbar sein und in keinem Fall irgendwelche Warnungen ergeben. (Siehe: Siehe Compiler-Direktiven, um einzelne Warnungen gezielt abzuschalten, wenn es gar nicht anders geht.)
Bitte benutzen Sie nicht die automatische Result-Variable in Funktionen. Wenn Sie sie haben wollen, so sollten Sie diese auch deklarieren:
function Foo (...) = Bar: Integer;
Benutzen Sie die Art der Deklaration mit =, nicht die ohne Gleichheitszeichen, es sei denn, Sie wollen PXSC-kompatibel sein.
Wenn eine Funktion einen Boolean-Wert liefert, um den Erfolg einer Operation anzuzeigen, so sollte True den Erfolg melden und False das Fehlschlagen. Beachten Sie, da� dieses Vorgehen anders ist als in C, wo 0 oftmals den Erfolg meldet.
Vermeiden Sie goto und �hnliche Statements, wie Exit, Return, Break und Continue. Vermeiden Sie goto um jeden Preis (au�er m�glicherweise ein nicht-lokales goto, um aus einer sehr tief geschachtelten rekursiven Funktion im Falle eines Fehlers herauszukommen). Vermeiden Sie die anderen Statements, wenn dies mit vertretbarem Aufwand m�glich ist. Wenn Sie aber daf�r eine weitere Boolean-Variable einf�hren m�ssten, so darf dies als Entschuldigung f�r das Benutzen dieser Statements gelten. Beachten Sie, da� Code oftmals einfacher wird, wenn Sie auf Break verzichten und stattdessen eine bessere Abbruchbedingung oder eine andere Sorte Schleife benutzen.
Niemals sollten Sie die for-Z�hlvariable ver�ndern oder dem Wert der Variablen nach dem Durchlaufen dieser Schleife vertrauen. (Das ist nicht nur eine Art, seinen Quelltext zu gestalten, sondern mehr noch eine Definition von Pascal. Solche Dinge ergeben undefinierte Ergebnisse.)
Vertrauen Sie niemals undefiniertem Verhalten. Als Beispiele dienen globale Variablen, die zu Beginn des Programmes mit 0 initialisiert zu sein scheinen, angeforderter Speicher, der initialisiert zu sein scheint, ein freigegebener Speicherbereich, dessen Inhalt immer noch g�ltig zu sein scheint oder die oben besprochenen for-Z�hlvariablen. Nichts von all dem ist garantiert und kann mit jeder Compilerversion oder Plattform ge�ndert werden. Undefiniert ist eben undefiniert. Und der Eindruck, da� solche Dinge bei 42 anderen Compilern zu funktionieren scheinen, ist dabei v�llig belanglos!
Bei Vergleichen sollte die sich h�ufiger �ndernde Variable auf der linken Seite stehen.
for i := 1 to 10 do
if a[i] = Foo then
for j := 1 to 10 do
if b[j] = a[i] then ...
In diesem Beispiel �ndert sich a[i] h�ufiger als Foo und b[j] �ndert sich h�ufiger als a[i] (da j sich h�ufiger als i �ndert).
Wir nehmen bei diesem Beispiel an, da� Foo konstant ist. Wenn Foo ebenfalls von i abh�ngt, so kann es angebracht sein, Foo auf die linke Seite zu stellen. Dies sollte dann aber durch einen Kommentar erl�utert werden.
Vermeiden Sie es, Code doppelt zu schreiben. Es ist zwar so einfach, den Code an eine andere Stelle zu kopieren, aber es wird ein Alptraum sein, diesen dann zu pflegen. Benutzen Sie stattdessen Routinen oder Subroutinen, Units oder Module. Planen Sie Ihren Code so, da� er erweitert werden kann. Packen Sie schlaue Tricks nicht an Stellen, die Sie sp�ter �ndern wollen.
Umfassen Sie einzelne Statements nicht mit begin und end, es sei denn, Sie wollen das “dangling else” - Problem vermeiden oder diese Zeile ist der gesamte Rumpf einer Prozedur bzw. Funktion! Siehe folgende Beispiele:
if foo then
begin
if bar then
baz
end { Vermeiden des ``dangling else'' - Problems. }
else
qux { Einzeiliges Statement. }
Schreiben Sie keine leere Unit-Initialisierung. Folgendes sollten Sie nicht tun:
...
procedure Foo;
begin
...
end;
begin
end.
Stattdessen schreiben Sie einfach:
...
procedure Foo;
begin
...
end;
end.
Schreiben Sie keine ungenutzten Deklarationen, au�er in Interfaces, wo diese vom importierenden Code genutzt werden k�nnen.
Denken Sie daran: Boolean-Werte sind Boolean-Werte! Bitte schreiben Sie if Foo then statt if Foo = True then, und if not Foo then statt if Foo = False then. Benutzen Sie auch until False statt until 1 = 0, das sieht auch h�bscher aus. Ein anderes Beispiel ist Foo := Expression statt if Expression then Foo := True else Foo := False.
Vermeiden Sie doppelte globale Bezeichner, �berladen Sie eingebaute Bezeichner nicht, obwohl es der GNU Pascal Compiler verschmerzen w�rde. Benutzen Sie dieselben globalen Bezeichner auch nicht in verschiedenen Units oder Modulen. (Dank “qualifizierter Bezeichner” w�re dies f�r den Compiler kein Problem, aber f�r den Benutzer verwirrend.)
Wir raten davon ab, globale Variablen f�r nicht-globale Zwecke
einzusetzen, z.B. eine globale Variable Counter als Z�hler in
diversen lokalen Routinen zu verwenden. Deklarieren Sie stattdessen
eine lokale Variable in jeder Routine, die eine ben�tigt. Dies
erm�glicht i.a. auch eine bessere Optimierung des erzeugten Codes.
Wenn Sie eine unendliche Schleife schreiben (auch wenn diese
m�glicherweise durch Break verlassen wird), empfehlen wir die
Verwendung der repeat und nicht der while Schleife,
weil dadurch der Code weniger weit nach rechts einger�ckt wird
(jedenfalls, sofern die Schleife mehr als eine Anweisung enth�lt).
Also:
repeat
...
until False
Und nicht:
while True do
begin
...
end
Wie in der GNU C-Bibliotheksdokumentation (see Consistency Checking (libc)) erl�utert, ist es h�ufig von Vorteil, grundlegende Annahmen in eigenen Programmen zu �berpr�fen. Schauen Sie sich dazu einmal folgende Prozedur an:
procedure MachWasMitPString (StrPtr: PString);
Hierbei k�nnten Sie implizit annehmen, da� diese Prozedur niemals mit
nil als Argument aufgerufen wird. Es ist jedoch sicherer, diese
“unm�gliche Bedingung” zu �berpr�fen, um sicher zu stellen, da�
StrPtr verschieden von nil ist:
procedure MachWasMitPString (StrPtr: PString);
begin
Assert (StrPtr <> nil);
...
end;
Wenn die �berpr�fung fehlschl�gt, dann erzeugt das Programm einen Laufzeitfehler. Daraus l��t sich der Schlu� ziehen, da� der Code, welcher diese Prozedur aufruft, fehlerhaft ist (oder diese Routine entsprechend erg�nzt werden sollte). Dieses Verfahren kann sich bei der Fehlersuche wirklich als hilfreich erweisen. Mit anderen Worten: fundamentale Annahmen am Anfang (oder einem anderen geeigneten Ort) einer Routine zu �berpr�fen stellt sicher, da� eine Funktion oder Prozedur nicht falsch benutzt werden kann.
Die GNU C-Bibliothek enth�lt das assert-Makro f�r diese Art von
�berpr�fungen. GNU-Pascals Assert verh�lt sich ein wenig anders.
Assert bricht das Programm nicht vollst�ndig ab, sondern erzeugt
einen Laufzeit-Fehler (see Assert (gpc)), den man z.B. mit der
Trap-Unit (see Trap (gpc)) abfangen kann.
Wenn das Programm hinreichend getestet wurde, kann man die
�berpr�fung von Assert abstellen, indem man das Programm mit
der Option --no-assertions neu compiliert. Am Code selbst ist
keine �nderung n�tig. Nebenwirkungen der Argumente von
Assert werden weiterhin ausgewertet (dies ist anders als
in C), so da� man weiterhin schreiben kann:
Assert (MeineFunktion (Foo, Bar) > 0)
MeineFunktion wird auf jeden Fall aufgerufen, die �berpr�fung,
ob der R�ckgabewert positiv ist, erfolgt jedoch nur, wenn
--no-assertions nicht als Option angegeben wurde.
Wir empfehlen, die Konsistenz�berpr�fung nie abzuschalten, sofern man den kleinen Laufzeitzuwachs verschmerzen kann.
Als erstes: Vermeiden Sie unn�tige Leerzeichen am Ende einer Zeile. Vergewissern Sie sich au�erdem, da� Sie den Quelltext nicht mit Tabulatorzeichen speichern. Verschiedene Editoren oder auch verschiedene Konfigurationen eines Editors interpretieren diese Zeichen mit einer unterschiedlichen Anzahl Leerzeichen. Dies gef�hrdet Ihre m�hsam erarbeitete Einr�ckung. (Wenn Sie GNU Emacs benutzen, so ist die Funktion untabify sehr n�tzlich; wenn sie VIM benutzen, die Umgebungsoption expandtab (:set et); in PENG kann die Option Expand tabs verwendet werden.)
Bitte vermeiden Sie es, in Ihren Quelltext Steuerzeichen einzuf�gen (au�er NewLine, selbstverst�ndlich). Bitte auch keine Form-Feeds (#12), wenngleich sie in den GNU Coding Standards zum Separieren von logischen Bereichen empfohlen werden. Auch keine SUB-Zeichen (#26), diese werden n�mlich unter DOS als Ende-der-Datei-Zeichen mi�braucht. �ltere DOS-Editoren f�gen dieses Zeichen an das Ende der Datei an, obwohl selbst das FAT-Dateisystem selbst �ber das Ende der Datei Bescheid wei�.
Wir empfehlen eine maximale L�nge von 68 Zeichen pro Zeile, so da� eine Quelldatei in TeX mit voreingestelltem Font auf A4 gedruckt werden kann. oder 78 Zeichen, geeignet f�r 80 Zeichen breite Bildschirme. Dies ist keine feste Regel, denn umgebrochene Zeilen verringern nur allzuoft die Lesbarkeit.
Benutzen Sie Leerzeilen zwischen Bl�cken. Bl�cke sind lange Kommentare, type, const, var, label Abschnitte, Routinen-R�mpfe, Unit- oder Modulinitialisierung/-finalisierung, interface, implementation, module, export, uses, import Zeilen, globale Compiler-Direktiven. Soweit lange Kommentare eine folgende Deklaration betreffen, bitten wir Sie, nur eine Zeile vor dem Kommentar abzusetzen, nicht zwischen Kommentar und Deklaration. Eine besondere Ausnahme ist zwischen den Bl�cken innerhalb derselben Routine. Benutzen Sie hier keine Leerzeilen:
procedure Short;
var
Foo: Integer;
Bar: Char;
begin
...
end;
Aber benutzen Sie Leerzeilen, um Subroutinen abzusetzen:
procedure Long;
const
...
var
Variablen, die von Sub genutzt werden k�nnen ...
procedure Sub;
var
...
begin
...
end;
var
Variablen, die nicht von Sub genutzt werden k�nnen ...
begin
...
end;
Benutzen Sie bitte auch keine Leerzeile nach der Deklaration des Namens der Hauptroutine, es sei denn, eine Subroutine folgt sofort. Andernfalls w�rde die Deklaration aussehen wie eine Forward-Deklaration.
Beachten Sie bitte, da� wir im obigen Beispiel die lokalen Variablen in Abschnitte vor und nach der Subroutine aufgeteilt haben. Dies ist nicht zwingend.
Alles, was wir �ber Subroutinen gesagt haben, gilt selbstverst�ndlich auch f�r Sub-Subroutinen beliebiger Verschachtelungstiefe.
Eine Leerzeile sollte dann zwischen Deklarationen desselben Types stehen, wenn es Sinn macht, um diese logisch zu separieren. Falls vor der Deklaration ein Kommentar steht, so soll die Leerzeile vor dem Kommentar stehen. Anderenfalls soll die Leerzeile vor der Deklaration stehen.
Leerzeilen k�nnen in langen Kommentaren Abs�tze teilen.
Keine Leerzeile am Anfang oder am Ende einer Datei. Lediglich ein einzelnes Zeilenendzeichen nach dem letzten end.. Niemals sollten Sie mehrere Leerzeilen hintereinander schreiben.
Die Kommentare sollten in geschweiften Klammern stehen, wie hier:
{ So ist es gut! }
Altmodische Kommentare zwischen Klammern und Sternchen sollten nicht mehr benutzt werden:
(* Ein h��licher Kommentar. So etwas braucht man nicht mehr! *)
Auch sollten keine Kommentare mehr geschrieben werden, die mit doppelten Schr�gzeichen eingeleitet werden und bis zum Ende der Zeile gehen:
// Machen Sie es nicht.
Obwohl ISO Pascal gemischte Kommentare ausdr�cklich erlaubt und der GNU Pascal Compiler sich mit der Option {$mixed-comments} auch nicht dar�ber beschweren w�rde, sollten solche Kommentare nicht benutzt werden:
(* Dieses ... }
{ ... und jenes. *)
Vermeiden Sie verschachtelte Kommentare wie { { diesen hier } }. Das ist nur dann in Ordnung, wenn Sie TeX in einem Kommentar setzen wollen oder �hnlich exotische Dinge. Was auch immer Sie f�r Gr�nde haben m�gen, m�ssen Sie diese Option dann zun�chst mit der Direktive {$nested-comments} anschalten. Benutzen Sie bitte nicht die Kommandozeilenoption --nested-comments. Packen Sie all diese Optionen in den Quellcode, damit niemand, der den Quellcode �bersetzen m�chte, erst die ben�tigten Optionen erraten mu�, und auch, weil Kommandozeilenoptionen z.B. bein Kompilieren eines Projektes mit mehreren Units/Modules alle Dateien betreffen w�rden.
Bitte schreiben Sie Kommentare in Englisch! Englisch ist diejenige Sprache, die die meisten Programmierer in allen L�ndern lesen k�nnen. Wenn Sie sich im Englischen nicht fit genug f�hlen, dann bitten Sie jemanden, Ihnen dabei zu helfen. Schreiben Sie so gut, wie Sie k�nnen.
Sie sollten sich “French Spacing” angew�hnen, d.h. nur ein Leerzeichen am Ende eines Satzes. Dabei k�nnen Sie in GNU Emacs M-a und M-e nicht benutzen. Wir hoffen, da� Sie das verschmerzen k�nnen. Bitte lassen Sie nur ein Leerzeichen nach der �ffnenden und der schlie�enden geschweiften Klammer des Kommentares Platz.
Wenn ein Kommentar sich nur auf eine Zeile Code bezieht, so sollte der Kommentar in derselben Zeile hinter dem Code stehen, soweit das m�glich ist. Bitte lassen Sie zwei Leerzeichen Platz. Dies ist ebenfalls f�r den Interface-Bereich einer Unit und bei globalen Variablen angemessen. Oftmals ben�tigt man diese Sorte Kommentare neben Record-Feldern. Andernfalls sollten Kommentare in eigenen Zeilen stehen:
{ foo bar baz }
Oder etwas l�nger:
{ foo bar
baz }
Mit Abs�tzen:
{ foo bar
baz
qux }
Die Kommentare sollten gew�hnlich vor den Code plaziert werden, auf den sie sich beziehen. Sie erhalten dieselbe Einr�ckung:
{ Meine Typen. }
type
...
type
{ Mein erster Typ. }
Foo = Integer;
...
begin
{ Mein erstes Statement. }
Bla;
{ Anfang der Schleife. }
repeat
{ Schleifenk�rper. }
...
{ Beende die Schleife, wenn irgendwas passiert. }
until Something
end;
Beachten Sie bitte besonders den Kommentar vor until.
Kommentare, die eine globale Deklarationen beschreiben, sollten in eigenen Zeilen direkt vor der Deklaration stehen:
{ Das ist Foo. Foo kann so Manches. }
procedure Foo;
Schreiben Sie keine “trivialen” Kommentare wie den obigen. Sie sollten Kommentare dadurch vermeiden, da� Sie durchdachten Code schreiben. Linus Torvalds macht das in seinem Kernel Coding Style deutlich:
Comments are good, but there is also a danger of over-commenting. Never try to explain how your code works in a comment: it's much better to write the code so that the working is obvious, and it's a waste of time to explain badly written code. Generally, you want your comments to tell what your code does, not how.
�bersetzung:
Kommentare sind grunds�tzlich sinnvoll, aber es besteht die Gefahr der “�berkommentierung”. Niemals sollten Sie im Kommentar erkl�ren, wie der Code arbeitet: Es ist viel besser, offensichtlichen Code zu schreiben, so da� seine Arbeitsweise sich ergibt. Es ist verschwendete Zeit, schlecht geschriebenen Code zu kommentieren. Allgemein sollte man mitteilen, was der Code macht, nicht wie er es macht.
(Beachten Sie, da� wir in anderen Bereichen ziemlich stark von seinem Coding Style abweichen.)
“Trickreicher” Code ist es wert, kommentiert zu werden. Wir definieren den Code als “trickreich”, der nicht naheliegende Dinge tut, auf nicht sofort einleuchtenden Annahmen basiert, unerwartete Implikationen beinhaltet, bei dessen �nderung etwas Spezielles beachtet werden muss, der sich nicht so verh�lt, wie es auf den ersten Eindruck scheint, der Seiteneffekte enth�lt oder es erfordert, da� andere Teile des Codes an anderer Stelle gleichzeitig mit ihm ge�ndert werden. Trickreicher Code sollte grunds�tzlich nur in bescheidenem Ma�e benutzt werden.
In dem Fall, da� sich ein Kommentar auf eine andere Stelle des Codes bezieht, wobei es egal ist, ob die Referenz in derselben oder einer anderen Datei liegt, beziehen Sie sich bitte auf den Namen der Routine oder einen Kontext. Bitte geben Sie den Bezug nicht in Form von Zeilennummern an (diese �ndern sich zu h�ufig). Lassen Sie in den Kommentaren au�erdem beide Stellen aufeinander verweisen, wo es Sinn macht. Diese Art der “Kreuzverweise” erwies sich schon oft als sinnvoll.
Code, der auskommentiert werden soll, sollte mit Hilfe von {$if False} ... {$endif} vom Kompilieren ausgeschlossen werden. Bitte benutzen Sie dazu keine Kommentare.
Um logische Abschnitte innerhalb gr��erer Module oder Units zu markieren, sollten Sie Kommentare benutzen. Wir schlagen Ihnen folgende leicht zu suchende festgelegte Form vor:
{@section Name des Kapitels}
{@subsection Name des Abschnitts}
Beachten Sie, da� in diesem Fall ausnahmsweise keine Leerzeichen neben den geschweiften Klammern eingef�gt werden.
Ein Modul, eine Unit oder Library sollte im Interface-Bereich Kommentare haben, so da� dieses Interface zu einer verl��lichen Dokumentationsquelle wird. Es ist freigestellt, solche Kommentare f�r Routinen zu benutzen, die nur im Implementationsbereich oder in Programmen (im Gegensatz zu Modulen etc.) deklariert werden. Mehrere zusammenh�ngende Deklarationen (z.B. Gruppen von Konstanten) k�nnen sich einen Kommentar teilen.
Es wird ein Utility namens pas2texi geschrieben, welches Texinfo-Dateien aus Pascal-Kommentaren erzeugt. Dieses Utility wird verschiedene Textauszeichnungsm�glichkeiten innerhalb von Kommentaren erlauben. Diese Textauszeichnungen werden innerhalb der Dokumentation von pas2texi oder in sp�teren Versionen dieses Dokumentes erl�utert werden.
“Fixme”-Kommentare dienen dazu, aufzuzeigen, da� an dieser Stelle Code etwas zu ver�ndern ist. Den Kommentaren werden mindestens zwei @ vorangestellt. F�gen Sie soviele @ ein, wie es der Dringlichkeit der Korrektur entspricht.
Die Kommentare sollten das Wesentliche des Problems enthalten, vor allem wenn die Wurzel des �bels woanderes liegt. Beispielsweise erkl�rt der Kommentar { @@fjf226 } den folgenden Code als Work-Around f�r ein Problem des GNU Pascal Compilers, welches von einem Test-Programm namens fjf226.pas verdeutlicht wird. (Diese Datei k�nnen Sie tats�chlich innerhalb des Quellpaketes des GNU Pascal Compilers finden.)
“Fixme”-Kommentare sollten nicht mit anderen Kommentaren vermischt werden. Wenn beide Kommentare gebraucht werden, so sollten sie getrennt, wenn auch direkt hintereinander stehen. Da sie vor�bergehender Natur sind, d�rfen solche Kommentare �berall stehen, sogar innerhalb von Anweisungen. Normalerweise stehen sie im Rumpf einer Routine, solange sie nicht das Interface eines Modules bzw. einer Unit beeinflussen. Interfaces, die voraussichtlich in der Zukunft ge�ndert werden, sollten @@-Kommentare direkt vor ihren beschreibenden Kommentaren aufweisen.
Jede Datei sollte mit einem Kommentar beginnen, welcher der Reihe nach folgendes beinhaltet:
Allgemein sollte man diese Deklarations-Reihenfolge einhalten:
Sie k�nnen von dieser Reihenfolge abweichen, wenn es notwendig erscheint oder den Code lesbarer gestaltet. Im folgenden sehen Sie ein Beispiel, bei dem diese Reihenfolge nicht eingehalten werden kann:
type
TIrgendwas = record
Dieses, Jenes: Integer
end;
const
IrgendEineKonstante = SizeOf (TIrgendwas);
Die obigen Regeln gelten selbstverst�ndlich auch f�r Deklarationsbereiche innerhalb von Routinen.
Wenn Sie mehrere mehr oder weniger unabh�ngige Bereiche in einer gro�en Unit oder einem gro�en Modul haben, so sollten sie obige Reihenfolge auf jeden Teilbereich des Modules anwenden. Es sollten z.B. nicht alle Konstanten aller Bereiche in eine einzelne const-Deklaration geschrieben werden, das macht den Code eher unleserlich.
Variablen, die nur im Hauptprogramm genutzt werden, m�ssen in Pascal global deklariert werden, wobei GNU Pascal eine Erweiterung kennt, um diese Beschr�nkung zu umgehen und Variablen im Anweisungsteil zu deklarieren (see var (gpc)). In einem solchen Fall sollten diese Variablen direkt vor dem begin des Hauptprogrammes geschrieben werden, nach allen Routinen etc. Das gilt besonders dann, wenn das Programm gro� ist und viele Variablen deklariert werden. Dadurch wird der Variablen-Deklarations-Bereich leichter einsehbar und ist einfacher mit den entsprechenden Code-Bereichen �nderbar. Au�erdem vermeidet man so, da� versehentlich Routinen diese Variablen nutzen.
Wenn Sie einen Typ und seinen zugeh�rigen Zeiger gleich mit deklarieren wollen, so deklarieren Sie bitte zuerst den Zeiger. Dies ist �bersichtlicher, besonders wenn der zugeh�rige Typ eine gr��ere Struktur (record oder object) ist. Auch wird es damit m�glich, rekursive Strukturen aufzubauen (Typdefinitionen, die Zeiger auf denselben Typ beinhalten). Bitte stellen Sie den Typen ein T, und den zugeh�rigen Zeigern ein P voran. Folgendes Beispiel veranschaulicht das:
type
PMyInt = ^TMyInt;
TMyInt = Integer;
PStrList = ^TStrList;
TStrList = record
Next: PStrList;
s: TString
end;
Bitte beachten Sie in dem Beispiel, da� das Next-Feld als erstes aufgef�hrt ist. Wir schlagen vor, da� Sie es bei rekursiven Typen immer so machen, es erm�glicht einige generische Listenroutinen und ist etwas effizienter, da beim Durchlaufen der Liste keine Offsets auftauchen.
Nicht verpflichtend ist es, alle Zeigertypen innerhalb einer type-Deklaration zuerst aufzuf�hren, aber wir raten Ihnen dazu. Hier ist ein Beispiel dazu:
type
{ Zeigertypen }
PFoo = ^TFoo;
PBar = ^TBar;
PBaz = ^TBaz;
{ Einige ma�gefertigte Integertypen }
TFoo = Integer attribute (Size = 16);
TBar = Cardinal attribute (Size = 16);
TBaz = Cardinal attribute (Size = 32);
Innerhalb von Objekt-Typen gibt es drei Deklarationsbereiche. Drei reservierte W�rter leiten diese Bereiche ein: public, protected, private. Innerhalb eines jeden dieser Bereiche sollte man folgende Reihenfolge einhalten:
Im Implementationsbereich sollte man dieselbe Reihenfolge einhalten wie bei der Deklaration. Dies gilt selbstverst�ndlich ebenso f�r Units und Module.
Benutzen Sie nie ein ; am Ende eines Blockes, also vor end, until, usw, au�er im Fall von case. Der letzte Zweig vor else (oder der letzte Zweig, wenn es keinen else-Zweig gibt) sollte ein abschlie�endes ; haben, um Probleme wie diese zu vermeiden:
case ...
Foo:
if Bar then { sp�ter eingef�gt }
begin
...
end { wenn es hier kein Semikolon gibt ... }
else { ... dann wird dieses else pl�tzlich dem then zugerechnet }
...
(Dasselbe gilt auch, wenn es if schon gibt und das else des case sp�ter eingef�gt wird.)
In Objekten mag es merkw�rdig aussehen, das ; nach dem letzten Eintrag (meistens eine Objekt-Methode) wegzulassen. Deswegen erlauben wir es hier und zur Erhaltung der Konsistenz auch in Records.
Reservierte W�rter sollten allesamt kleingeschrieben werden, einschlie�lich aller Direktiven und W�rter, die nur in manchen Kontexten reserviert sind (wie protected). Wenn Sie Direktiven au�erhalb ihres Kontextes als Bezeichner benutzen (was leicht zu Problemen f�hren kann), so schreiben Sie diese bitte wie Bezeichner.
Als besondere Ausnahme darf man File gro�schreiben, wenn dieses als eigener Typ gebraucht wird. Anders ist es selbstverst�ndlich bei file of Char. Im Fall von procedure als Typ (Borland Pascal) kann man diese Regel nicht anwenden, denn File kann ein Typ an sich sein, w�hrend procedure ein Typ-Konstruktor ist. Beispiel:
procedure Foo (var a: File); { Das geht }
procedure Foo (var a: procedure); { Das geht nicht! }
Der n�chste Punkt betrifft die Gro�schreibung von Bezeichnern. Es gibt hierbei keinen Unterschied zwischen eingebauten und selbstdefinierten Bezeichnern. Grunds�tzlich sollte nur der erste Buchstabe gro�geschrieben werden, au�er wenn es sich um zusammengesetzte W�rter oder Akronyme handelt, dann sollte jeder Anfangsbuchstabe eines jeden Teilwortes gro�geschrieben werden. Unterstriche sollten vermieden werden. Akronyme, die zu einem Teil der nat�rlichen Sprache geworden sind, sollten so geschrieben werden wie in der Sprache. Beispielsweise Dos oder DOS, aber immer GPC und niemals Gpc! Hier einige Beispiele von Bezeichnern: Copy, Reset, SubStr, BlockRead, IOResult, WriteLn, Sqr, SqRt, EOF, EOLn.
Anders als bei C-Makros gelten diese Regeln auch f�r Konstanten.
Sehr kurze Bezeichner d�rfen kleingschrieben werden, z.B. i, s1 oder xx. Solche kurzen Bezeichnernamen sollten nur in lokalen Bl�cken auftauchen. Dazu z�hlen auch Parameter globaler Routinen, denn der G�ltigkeitsbereich solcher Parameter ist lokal. Der Gebrauch dieser Bezeichner sollte nicht in einem globalen Kontext erfolgen, besonders nicht in Units oder Modulen. Der Autor kann ja nie wissen, in welchen Kontexten die Units/Module benutzt werden.
Bitte bleiben Sie einheitlich, was die Gro�- und Kleinschreibung ihrer Bezeichner anbelangt. Wenngleich Pascal Sie auch nicht schl�gt, wenn Sie mal die Gro�schreibung einer Variablen innerhalb eines Blockes �ndern: Bitte halten Sie sich an eine Form.
F�r Bezeichner f�r die Werte von Aufz�hlungstypen und f�r Gruppen von Konstanten, d.h. an Stellen, wo viele Bezeichner auf einmal eingef�hrt werden, kann es n�tzlich sein, ein zweibuchstabiges kleingeschriebenes Pr�fix zu verwenden, dem im Gegensatz zu obigen Regeln ein Unterstrich (_) folgt:
type
TFooBar = (fb_Foo, fb_Bar, fb_Baz, fb_Qux);
{ Meine Foos }
const
mf_Foo = 1;
mf_Bar = 3;
mf_Baz = 42;
In objektorientiertem Code, meistens in Konstruktoren, hat man den Fall, da� der Parameter einer Funktion zu einem Feldnamen passen soll, den dieser Parameter initialisiert. Da beide Namen nicht �bereinstimmen d�rfen, sollte das Feld den “nat�rlichen” Namen haben, da es an mehreren Stellen verwendet wird, und der Parametername ver�ndert werden. Wir haben bislang keine einheitliche Regel f�r den Namen des Parameters in einem solchen Fall gefunden. Manche Programmierer verwenden a als Pr�fix. Wenn Sie eine gute Idee haben, so lassen Sie es uns wissen.
Makros sollten nicht genutzt werden! Sie sind die Reinkarnation des B�sen! Wenn Sie es doch tun, so m�ssen Sie zur Strafe alle Buchstaben gro� schreiben und einzelne Teilw�rter mit Unterstrichen trennen. Da Makros au�erhalb der Pascal-Geltungsbereiche stehen, macht es durchaus Sinn, sie anders zu schreiben als den �brigen Pascal-Code. Das gilt ebenso f�r Bedingungen im Rahmen der bedingten Kompilierung (Conditionale).
Anmerkung des �bersetzers: Um der Doppeldeutigkeit von “condition”, wie sie in einer if-Anweisung vorkommt, und wie sie in der bedingten Ausf�hrung von Code vorkommt, Herr zu werden, habe ich mich entschieden, in diesem Abschnitt durchg�ngig “Conditional” im letztgenannten Kontext zu verwenden. Der Leser m�ge mir verzeihen.
Grunds�tzlich sollten Sie so wenig Compiler-Direktiven wie nur irgend m�glich verwenden, weil sie den Code schwerer lesbar und wartbar machen. So sollten Direktiven aussehen:
{$Ihre-Compiler-Direktive}
und niemals so: (see Kommentare)
(*$mach-es-nicht-Direktive*)
und auch nicht so, weil dies im Gegensatz zu Pascal, von Zeilenumbr�chen anh�ngt:
#so-auch-nicht-Direktive
Dasselbe bei Makro-Definitionen:
{$define ...}
Dies spart au�erdem den Backslash vor dem Zeilenumbruch, im Gegensatz zu #define. Aber Sie wollen ohnehin keine Makros benutzen, ODER? (see Gro�schreibung)
F�gen Sie niemals ein Leerzeichen vor der schlie�enden Klammer ein, denn es darf auch keines nach der �ffnenden Klammer kommen. Wenn Sie mehrere Direktiven zusammenf�gen, so f�gen Sie zwischen zweien kein Leerzeichen ein, ein einfaches Komma gen�gt.
Es sollten keine Kommentare innerhalb der Direktiven eingef�gt werden. Schreiben Sie Kommentare stattdessen separat:
{$X+} { Wir brauchen erweiterte Syntax }
Borland Pascal erlaubt, Kommentare mit Direktiven zu vermischen. Das ist ein Mi�brauch eines solchen Kommentares!
Kurze Formen der Direktiven sind in Ordnung, aber man sollte den langen Formen den Vorzug geben. Die kurzen Formen m�ssen gro�geschrieben werden, w�hrend die langen Formen kleingeschrieben werden sollten (ausgenommen Argumente, bei denen es auf die richtige Schreibweise ankommt, wie Fehlermeldungen, Warnungen, Dateinamen – bei letzteren ist auch unter DOS die korrekte Gro�- und Kleinschreibung zu verwenden, damit der Code portabel bleibt).
Sie k�nnen verschiedene Direktiven kombinieren, dabei auch kurze und lange Formen mischen, wie im folgenden Beispiel:
{$gnu-pascal,I-,X+}
Jede Unit und jedes Modul sollte {$gnu-pascal,I-} oder {$gnu-pascal,I+} nahe am Anfang stehen haben, und zwar nach dem einleitenden Kommentar mit der Beschreibung und der Lizenz. {$gnu-pascal} bewirkt, da� die Unit ohne Dialekt-Optionen kompiliert wird, selbst wenn das aufrufende Programm Dialekt-Optionen nutzt. {$I-} und {$I+} zeigen dem Nutzer der Unit, da� Ein-/Ausgabe-Fehler von den Routinen abgefangen werden oder Laufzeitfehler zu erwarten sind. Der erste Fall ist dem anderen in den meisten F�llen vorzuziehen. F�r Programme ist dies optional. Routinen, die Ein-/Ausgabe-Fehler hervorrufen k�nnen, sollten mit dem Attribut iocritical (see attribute (gpc)) deklariert werden:
procedure KritischeRoutine; attribute (iocritical);
{$W-} (keine Warnungen) sollte nur lokal genutzt werden und ein “FIXME”-Kommentar (see Kommentare) haben, denn es zeigt ein Problem mit dem Code oder dem Compiler.
Bitte schalten Sie keine Warnungen ab, wenn Sie nur zu faul sind, Code zu schreiben, der keine Warnungen produziert.
Jeder Compiler-Schalter, der nicht global gesetzt wird (beispielsweise zusammen mit {$gnu-pascal}, siehe oben), sollte mit {$local ...} kombiniert werden. Also nicht so:
{$I-} Reset (f); {$I+}
Sondern so:
{$local I-} Reset (f); {$endlocal}
Das erste Beispiel ist falsch, wenn vorher schon {$I-} geschrieben wurde. Selbst wenn ein Programmierer wei�, welches die aktuellen globalen Einstellungen sind, so k�nnen sich diese eines Tages �ndern. Auch dadurch, da� Teile des Codes an eine andere Stelle kopiert werden. Das untere der beiden Beispiele ist daher die sichere Form.
Um zu verdeutlichen, was wir meinen, hier noch ein Beispiel:
{$local W-} Foo; {$endlocal} { @ GPC gibt hier eine �berfl�ssige Warnung }
Nochmal: Vermeiden Sie es, lokale Direktiven zu gebrauchen. {$I-} kann manchmal n�tztlich sein. {$X+} sollte nur dann gebraucht werden, wenn es wirklich notwendig ist, und dann auch bitte so lokal wie nur irgend m�glich. Vermeiden Sie Zeiger-Arithmetik!
Benutzen Sie weder {$X+} noch {$ignore-function-results}, um Funktionswerte zu �berpr�fen. Es ist schlicht zu einfach, ein beachtenswertes Funktionsergebnis zu ignorieren. Manchmal, besonders dann, wenn man eine C-Bibliothek linkt, hat man es mit Funktionsergebnissen zu tun, die �berfl�ssig erscheinen, weshalb man sie nicht �berpr�fen m�chte. Solche Funktionen lassen sich bald mit dem Attribut ignorable deklarieren, so da� das Funktionsergebnis stillschweigend ignoriert wird.
Benutzen Sie auch dann Dummy-Variablen, wenn Sie Funktionsergebnisse von Funktionen, deren Ergebnisse gemeinhin nicht ignoriert werden sollen, ignorieren wollen. �berpr�fen Sie sehr sorgf�ltig, ob ein solches Ergebnis wirklich sicher ignoriert werden kann! Wenn jedoch ein unerwarteter Wert Sie in eine “unm�gliche” Situation bringen w�rde, so ist es normalerweise besser, das Funktionsergebnis zu �berpr�fen und im unerwarteten Fall eine Warnung auszudrucken oder gar abzubrechen. Tun Sie das wenigstens dann, wenn DEBUG gesetzt ist. (see Compiler-Direktiven).
Linker-Direktiven, d.h. {$L} f�rBibliotheken und C-Code-Dateien (oder Dateien anderer Sprachen) sollten nahe am Anfang des Programmes und nahe am Implementationsanfang von Units oder Modulen stehen. Mehrere Bibliotheken und C-Quelldateien k�nnen in eine Direktive geschrieben werden, wenn sie logisch zusammengeh�ren (bspw. eine Bibliothek und ihre zugeh�rige Wrapper-Funktion), nicht aber dann, wenn sie nicht zusammengeh�ren. Diese Direktiven sollten nicht mit anderen Direktiven gemischt werden (was auch nicht geht, wenn L zuerst angef�hrt wird; anders herum geht es, ist aber nicht ratsam). Die externen Deklarationen der Bibliothek oder C-Routinen sollten sofort der zugeh�rigen Direktive folgen (au�er f�r Units oder Module bei denjenigen Deklarationen, die in das Interface geh�ren). Das Benutzen von {$L} innerhalb eines Programmes ist normalerweise keine gute Idee. Da lohnt es sich schon, eine Unit zu schreiben, welche abstrahiert und wiederverwertet werden kann.
Bedingtes Kompilieren kann manchmal n�tzlich sein, aber es sollten sowenige {$ifdef}s wie nur irgend m�glich geschrieben werden, denn sie vermindern die Lesbarkeit des Codes sehr stark. Wo Conditionale eingesetzt werden, um verschiedene Systeme zu unterscheiden, sollten die F�higkeiten des Systems (bspw. __BYTES_LITTLE_ENDIAN__) oder Gruppen von Systemen (bspw. __OS_DOS__) �berpr�ft werden, nicht einzelne Systeme. Dieses Vorgehen funktioniert dann oftmals auch sp�ter noch auf Systemen, von denen man noch nichts wei� oder die noch nicht existieren.
Wann immer dies m�glich ist, sollte vordefinierten Konstanten der Vorzug gegen�ber defines gegeben werden (bspw. BytesBigEndian, OSDosFlag). Dies ist im Anweisungsteil m�glich (der “immer false” - Zweig wird schlicht wegoptimiert, trotzdem wird seine Syntax �berpr�ft). Bei Typen-Deklarationen ist es normalerweise nicht m�glich. Hier mu� man defines einsetzen. Folgendes ist ein Beispiel aus der CRT-Unit:
TWindowXYInternalCard8 = Cardinal attribute (Size = 8);
TWindowXYInternalFill = Integer attribute (Size = BitSizeOf (Word) - 16);
TWindowXY = packed record
{$ifdef __BYTES_BIG_ENDIAN__}
Fill: TWindowXYInternalFill;
y, x: TWindowXYInternalCard8
{$elif defined (__BYTES_LITTLE_ENDIAN__)}
x, y: TWindowXYInternalCard8;
Fill: TWindowXYInternalFill
{$else}
{$error Endianness is not defined!}
{$endif}
end;
Das DEBUG-Flag sollte eine Unterst�tzung beim Debuggen des Codes sein, also Code, der die Funktionalit�t beim Debuggen nicht ver�ndert. Nur daf�r sollte er eingesetzt werden. Programme m�ssen mit und ohne DEBUG lauff�hig sein. Es kann sein, da� der Code mit DEBUG langsamer l�uft und eine Vielzahl von Mitteilungen produziert. Diese Mitteilungen sollten klar als Debug-Mitteilungen erkennbar sein, bspw. dadurch, da� der Ausgabe ein DEBUG: vorangestellt wird. Solcher Code darf auch einfach abbrechen, wenn fehlerhafte oder merkw�rdige Zust�nde eintreten.
Conditionale k�nnen ebenfalls herangezogen werden, um verschiedene Versionen ein und desselben Codes anzufertigen. So ist es z.B. innerhalb eines Mathematik-Programmes m�glich, eine eigene Version mit GMP-Zahlen (GMP ist eine Bibliothek zur Bearbeitung beliebig gro�er Zahlen) zu erzeugen und eine ohne, je nachdem, welches Conditional gesetzt ist. In diesem Fall sollten die Namen und Bedeutungen aller Conditionale in einem weit oben im Quelltext stehenden Kommentar erkl�rt werden. Sehen Sie sich bitte __BP_TYPE_SIZES__, __BP_RANDOM__ und __BP_PARAMSTR_0__ als Beispiele aus der Unit System an. Der Code sollte mit jeder Kombination dieser Conditionale kompilierbar sein, was bedeutet, eine exponentielle Menge an Kombinationen zu testen. Noch ein guter Grund, Conditionale so selten wie m�glich zu benutzen oder gar zu vermeiden.
Eine andere denkbare Benutzung von Conditionalen besteht darin, mit ihrer Hilfe verschiedene Implementationen desselben Codes anzufertigen. Sie sollten diese Strategie nur dann anwenden, wenn alle Implementationen unterst�tzt werden oder es geplant ist, sie zu unterst�tzen. Andernfalls sollte die alte Implementation besser ins Museum wandern. Halten Sie den Code in einem solchen Fall besser “sauber”. Die Hinweise bzgl. des Testens gelten auch hier.
Wenn Sie es mit komplizierten Conditionalen zu tun haben, so folgen Sie bitte der Pascal-Syntax. Formatieren Sie den Code nach den Regeln von Pascal, nicht nach denen von C. Hier ein dummes Beispiel:
{$if defined (Foo) or False}
Im Gegensatz zu (bitte nicht nachmachen!):
{$if defined (Foo) || 0}
Oder noch schlimmer:
#if defined (Foo) || 0
Eine spezielle Conditionale kann genutzt werden, um Code kurzfristig auszukommentieren. Hier ist die zugeh�rige Syntax:
{$if False} ... {$endif}
Ein Standard-Conditional sollte in Programmen, Units oder Modulen genutzt werden, wenn Sie sicherstellen wollen, da� die richtige Version des GNU Pascal Compilers verwendet wird. Folgen Sie diesem Beispiel:
{$if __GPC_RELEASE__ < 20020510}
{$error This unit requires GPC release 20020510 or newer.}
{$endif}
Im allgemeinen sollten nie mehrere Leerzeichen aufeinander folgen, au�er f�r Einr�ckungen und in speziellen F�llen, die im folgenden Beschrieben werden.
Ein einzelner Blank soll vor und nach Operatoren, Zuweisungen (:=) und .. stehen. In Write, WriteLn und WriteStr sollte ein Blank um das : angebracht werden. Ein einzelner Blank soll nach Kommata und anderen : stehen. Folgendes Beispiel macht es deutlicher:
var
Foo: Integer;
...
begin
Foo := 42;
WriteLn (Foo + 3 : 5, ' bar')
end;
Kein Leerzeichen sollte hingegen nach dem un�ren Minuszeichen - stehen. Dieses sind die korrekten Formen: x - 1, -x und -1.
Ein Leerzeichen sollte vor und eines nach den Klammerzeichen (() und ()) stehen, solange diese nicht neben anderen Klammern, eckigen Klammern, dem Pointer-Symbol (^), einem Semikolon oder einem Komma auftreten. Mit anderen Worten: Ein Leerzeichen sollte zwischen Bezeichnern/Schl�sselw�rtern und der �ffnenden Klammern stehen. Beispiel:
Foo (Bar^(Baz[Qux * (i + 2)]), Fred (i) + 3);
F�r Arrayindizierung wird kein Leerzeichen verwendet (schreiben Sie Foo[42] anstelle von Foo [42]), jedoch schon bei Arraydeklarationen:
Foo: array [1 .. 42] of Integer;
Bei Mengen-Konstruktoren sollte ggf. ein Blank vor der �ffnenden Klammer stehen – diese eckigen Klammern sollten wie normale Klammern behandelt werden:
x := [0, 2 .. n];
Aber:
Foo ([1, 2, 3]);
Kein Leerzeichen bei . und ^:
Rec.List^.Next^.Field := Foo
Wie wir schon ausf�hrten, soll je ein Blank nach den �ffnenden und vor den schlie�enden geschweiften Klammern in Kommentaren stehen. Dies gilt jedoch nicht f�r Compiler-Direktiven. Au�erdem sollten vor Kommentaren, die einer Code-Zeile folgen, zwei Leerzeichen stehen:
Inc (x); { Increment x. }
Wenn Sie m�gen, so f�gen Sie beliebig viele Leerzeichen ein, um “tabellarisch” aussehenden Quellcode zu erzeugen. Unserer Meinung nach erh�ht dies die Lesbarkeit des Codes ungemein, weil der menschliche Geist auf solche Strukturen trainiert ist, Unterschiede in Zeilen besser gesehen werden k�nnen, und man bei �nderungen im Quellcode verwandte Stellen nicht so leicht �bersieht. Eine Anwendung dieser Prinzipien sollte in Interface-Deklarationen zu finden sein (es ist nicht leicht anwendbar, wenn jede Routine durch Kommentare getrennt wird, daher ist in einem solchen Fall m�glicherweise ein gemeinsamer Kommentar empfehlenswert):
function Pos (const SubString, s: String): Integer;
function LastPos (const SubString, s: String): Integer;
function PosCase (const SubString, s: String): Integer;
function LastPosCase (const SubString, s: String): Integer;
function CharPos (const Chars: CharSet; const s: String): Integer;
function LastCharPos (const Chars: CharSet; const s: String): Integer;
function PosFrom (const SubString, s: String; From: Integer): Integer;
function LastPosTill (const SubString, s: String; Till: Integer): Integer;
function PosFromCase (const SubString, s: String; From: Integer): Integer;
function LastPosTillCase (const SubString, s: String; Till: Integer): Integer;
Ebenfalls m�glich:
procedure Foo;
function Bar ...;
procedure Baz;
Und nat�rlich:
const
FooBar = 1;
Baz = 2;
Quux = 3;
Dieselbe “Tabellenanordnung” kann man f�r Initialisierungen gebrauchen:
const
Foo: TBarArray =
(('Foo' , 3),
('Bar baz', 42),
('' , -1));
Und in case-Anweisungen:
case ReadKeyWord of
kbLeft : if s[n] > l then Dec (s[n]) else s[n] := m[n];
kbRight : if s[n] < m[n] then Inc (s[n]) else s[n] := l;
kbUp : if n > 1 then Dec (n) else n := 5;
kbDown : if n < 5 then Inc (n) else n := 1;
kbHome : s[n] := l;
kbEnd : s[n] := m[n];
kbPgUp,
kbCtrlPgUp: n := 1;
kbPgDn,
kbCtrlPgDn: n := 5;
kbCR : Done := True;
end
Und auch je nach Geschmack in anderem Code:
WriteCharAt (1, 1, 1, Frame[1], TextAttr);
WriteCharAt (2, 1, w - 2, Frame[2], TextAttr);
WriteCharAt (w, 1, 1, Frame[3], TextAttr);
Zeilenumbr�che sind nach lokalen const-, type- und var-Deklarationen freigestellt, wenn sie nur eine einzige Deklaration beinhalten (Sie k�nnen auch mehrere Bezeichner in einer Zeile deklarieren/definieren):
procedure Baz;
var Foo, Bar: Integer;
begin
...
end;
Das geht auch:
procedure Baz;
var
Foo, Bar: Integer;
begin
...
end;
Aber bitte nicht so:
procedure Baz;
var Foo, Bar: Integer;
Qux: Real;
begin
...
end;
Wenn Sie viele Deklarationen haben, so k�nnen Sie Zeilenumbr�che auf verschiedene Weisen vornehmen. Folgendes Beispiel ist die bevorzugte Fassung f�r var-Deklarationen:
var
Foo, Bar, Baz, Qux, Quux, Corge, Grault, Garply, Waldo, Fred,
Plugh, Xyzzy, Thud: Integer;
oder:
var
Foo, Bar, Baz, Qux, Quux, Corge, Grault, Garply, Waldo: Integer;
Fred, Plugh, Xyzzy, Thud: Integer;
Die folgende Form ist eher bei der Definition von record- oder �ffentlichen object-Feldern gebr�uchlich, besonders, wenn jeder Zeile ein Kommentar folgt:
var
Foo,
Bar,
Baz,
Qux: Integer;
Kein Zeilenumbruch darf nach var-Deklarationen innerhalb von Bl�cken erfolgen. Solche Zeilenumbr�che setzen das falsche Signal, da� hier mehrere Deklarationsgruppen erlaubt w�ren:
Foo := Bar;
var Baz: array [1 .. Foo] of Integer;
Da dieses Statement eine GNU Pascal Erweiterung ist, sollte es selten eingesetzt werden, bei Variablen, deren Gr��e erst innerhalb der Routine berechnet wird oder f�r Variablen innerhalb von Modul-/Unit-Initialisierungen beispielsweise, um daf�r keine globalen Variablen zu ben�tigen. Denken Sie bitte bei der Anwendung dieses Features �ber Unterroutinen nach.
F�gen Sie bitte keinen Zeilenumbruch nach label durch. Sie sollten Label folgenderma�en deklarieren:
label Foo, Bar, Baz;
So sollten Sie es auf keinen Fall tun:
label
Foo,
Bar,
Baz;
Verschiedene Deklarationen von Labeln in unterschiedlichen Zeilen funktionieren auch nicht:
label
Foo;
Bar;
Baz;
Hier folgt ein Beispiel, wie man innerhalb eines case-Blockes Zeilen umbricht:
case
foo:
begin
...
end;
bar,
baz .. qux:
...
else
...
end;
Oder auch “tabellarisch”:
case
foo: begin
...
end;
bar,
baz .. qux: ...
else ...
end;
Lange Zeilen sollten immer vor oder immer nach Operatoren, sowie nach Kommata umbrochen werden, wobei die Einr�ckung die Gruppierungen verdeutlichen sollte:
if (x = y)
and (foo
or (bar
and (baz or qux))
or fred) then
Oder so:
if (x = y) and
(foo or
(bar and
(baz or qux)) or
fred) then
Hier sehen Sie, wie Sie Zeilenumbr�che innerhalb von if-then-else Anweisungen vornehmen k�nnen. Diese Art der Einr�ckung sollte auch verwendet werden, wenn Sie die case-Anweisung verwenden w�rden, dies aber nicht m�glich ist (weil die Typen nicht aufz�hlbar sind, oder die Werte nicht konstant sind oder ein Vergleich die Benutzung einer Funktion wie StrEqualCase notwendig machen w�rde, oder zus�tzliche Bedingungen auftauchen):
if ... then
a
else if ... then
b
else
c
Wenn a und “nicht a” die Hauptf�lle sind und b und c Unterf�lle von “nicht a”, so benutzen Sie bitte die folgende Form (die Unterscheidung ist manchmal Geschmackssache):
if ... then
a
else
if ... then
b
else
c
Das folgende (biologisch gesehen ziemlich unvollst�ndige) Beispiel enth�lt eine Mischung beider Formen, die wir f�r vern�nftig halten:
if Wohnort = 'Wasser' then
{ Im Wasser lebende Tiere }
WriteLn ('Ist es ein Fisch?')
else if Wohnort = 'Luft' then
{ Lufttiere }
WriteLn ('Ist es ein Vogel?')
else
{ Landlebewesen }
if Beine = 8 then
WriteLn ('Ist es eine Spinne?')
else
WriteLn ('Ist es ein Gnu?')
Die Hauptf�lle werden hier durch den Wohnort bestimmt, die Anzahl der Beine bestimmen einige untergeordnete F�lle.
Hier eine kurze Zusammenfassung der normalen Schleifen:
for ... do
...
while ... do
...
repeat
...
until ...
Wenn nur eine einzelne Anweisung nach if oder in einer do- oder for-Schleife bzw. zwischen repeat und until existiert und diese Anweisung kurz genug f�r eine Zeile ist, so darf diese Anweisung in eine Zeile wie folgt geschrieben werden:
if ... then ...
for ... do ...
while ... do ...
repeat ... until ...
Wenn mehrere Anweisungen mit begin und end in einen Block gefa�t werden, sieht es folgenderma�en aus:
if ... then
begin
...
end
for ... do
begin
...
end
while ... do
begin
...
end
Es wird nach folgenden Ausdr�cken 2 Leerzeichen einger�ckt: begin, then, else, case, do (for, while, with, to begin, to end), repeat, record, object, type, const, var, label.
Globale Routinen und ihre lokalen Variablen etc. werden nicht einger�ckt, ebenso wie globale Variablen etc. Jede Subroutine (Kopf und K�rper sowie ihre lokalen Variablen etc.) soll einger�ckt werden.
program Prog;
var
GlobalVar: Integer;
procedure GlobalProc;
var LocalVar: Integer;
procedure LocalProc;
var LocalLocalVar: Integer;
begin
WriteLn ('Dies ist eine lokale Prozedur.')
end;
begin
WriteLn ('Dies ist eine globale Prozedur.')
end;
begin
WriteLn ('Dies ist das Hautpprogramm.')
end.
Variante Records sollten so einger�ckt werden:
type
Foo = record
NonVariant: Foo;
case Discriminant: Bar of
Val1: (Variant1: Baz;
Variant2: Qux);
Val2: (Variant3: Fred)
end;
var
Foo: record
[ wie oben ]
end = [ Initialisierung ]
Gr��ere Einr�ckung (mehr als zwei Leerzeichen) kann bei Zeilenumbr�chen im Code erfolgen, um einen “tabularen” Code zu erzeugen.
Conditionale ({$ifdef}) sollten dieselbe Einr�ckung wie der zugeh�rige Code haben:
begin
{$ifdef DEBUG}
WriteLn ('Debugging-Version');
{$endif}
...
end;
Kurze Conditionale, die sich nur auf einen Ausdruck beziehen, d�rfen auch in eine Zeile geschrieben werden:
Foo := {$ifdef DEBUG} 'Debugging' {$else} 'Ver�ffentlichung' {$endif};
Wenn Conditionale beabsichtigterweise entgegen den normalen syntaktischen Regeln genutzt werden, so setzen Sie diese an passende Stellen und schreiben Kommentare dazu:
begin
{ F�hre den Code bedingungslos aus, wenn wir debuggen }
{$ifndef DEBUG}
if EinigeBedingungen then
{$endif}
begin
...
end
end;
Oftmals finden Sie sch�nere und nicht weniger effiziente Wege, dasselbe zu schreiben. In diesem Fall kann es auch so erfolgen:
begin
if {$ifdef DEBUG} True {$else} EinigeBedingungen {$endif} then
begin
...
end
end;
Oder noch besser:
{ global }
const
DebugFlag = {$ifdef DEBUG} True {$else} False {$endif};
begin
if DebugFlag or EinigeBedingungen then
begin
...
end
end;
Die meisten der bisherigen Regeln gelten nicht innerhalb von Strings. Allgemein sollten Textausgaben innerhalb von Zeichenketten den GNU Coding Standards folgen. Beispielsweise sollten zitierte Namen von ` und ' begrenzt werden. In Pascal bedeutet das, da� Sie doppelte ' benutzen m�ssen. Mehr Informationen: Siehe Errors (standards).
Normalerweise sollten Strings in einfachen Anf�hrungszeichen so wie 'dieser sch�ne Satz, den Sie lesen' eingeschlossen sein. Mit doppelten Anf�hrungszeichen sollen nur Zeichenketten umfa�t werden, die C-Escape-Sequenzen beinhalten, wie "\t". Beachten Sie bitte, da� NewLine ("\n") vordefiniert ist. Geben Sie daher NewLine den Vorzug, wenn Sie nicht gerade C-Strings f�r andere Zwecke ben�tigen.
Mehrzeilige Strings k�nnen folgenderma�en genutzt werden:
WriteLn ('Hallo
Welt!')
Oder (diese Form ist vor allem dann vorzuziehen, wenn der String selbst Einr�ckungen und/oder Abs�tze enth�lt):
WriteLn (
'Hallo
Welt!')
Folgendes ist auch m�glich:
WriteLn ('Hallo' + NewLine + 'Welt!')
(Beachten Sie, da� obiger Code nicht ohne die Unit GPC
kompiliert werden kann.)
Oder nat�rlich:
WriteLn ('Hallo');
WriteLn ('Welt!')
Wenn Sie testen m�chten, ob ein String leer ist, benutzen Sie folgende Syntax:
if s = '' then
...
Der GNU Pascal Compiler optimiert dies automatisch zu folgendem schnelleren Test. Daher k�nnen Sie den vorhergehende, k�rzere Schreibweise ohne Bedenken verwenden:
if Length (s) = 0 then
...
Dasselbe gilt nat�rlich auch f�r <> und sogar f�r Zuweisungen, bei denen s := '' die empfohlene Form ist, welche von GPC intern zu SetLength (s, 0) optimiert wird.
Bitte beachten Sie die entsprechende Beschreibung in der GPC-Dokumentation (see I18N (gpc)).
Dieser Abschnitt der GNU Coding Standards kann so, wie er ist, auf GNU Pascal �bertragen werden. Beachten Sie, da� mmap hier MemoryMap bedeutet. Siehe Mmap (standards).
Wir empfehlen Ihnen, das entsprechende Kapitel der GNU Coding Standards zu lesen Siehe Documentation (standards), die dortigen Informationen gelten auch f�r GNU Pascal. Einige Anmerkungen haben wir aber trotzdem.
Es w�re sch�n, eine Man-Page f�r jedes Programm zu haben. Diese Man-Page sollte auf eine Info-Dokumentation verweisen. Es existiert ein GNU Programm namens help2man, welches Man-Pages aus der Ausgabe der --help- und --version-Optionen Ihres Programmes generiert. Es funktioniert gut, bis auf die Tatsache, da� es FSF an den Anfang der Man-Page schreibt, was nicht f�r jedes mit dem GNU Pascal Compiler erzeugte Programm richtig ist. Dies kann jedoch leicht mit der Hand oder automatisch mit einem Programm wie sed ge�ndert werden.
Geben Sie sich mit den Man-Pages nicht zuviel M�he. Sie gleichzeitig mit der Texinfo-Dokumentation auf dem neusten Stand zu halten, bedeutet eine Menge Arbeit und ist m�glicherweise sehr fehlertr�chtig. Wenn Sie die Man-Page nicht auf dem neuesten Stand halten, so schafft sie mehr Verwirrung als Nutzen.
Auf der einen Seite fehlen wichtige Informationen, wenn Man-Pages zu knapp ausfallen, auf der anderen Seite werden l�ngere Man-Pages sehr un�bersichtlich.
Mit anderen Worten: Schreiben Sie Info- (bzw. Texinfo-)Dokumentation!
Bitte lesen Sie das entsprechende Kapitel der GNU Coding Standards. Beachten Sie, da� der ganze Aufwand mit den auto-Tools (autoconf, automake, ...) im Rahmen von GNU Pascal normalerweise nicht gebraucht werden. Au�erdem sind Makefiles in GNU Pascal Programmen nicht immer notwendig. Siehe Managing Releases (standards).
F�r Ihre Pascal-Projekte ben�tigen Sie keine gro�en Makefiles und Sie brauchen sich ebenfalls nicht in autoconf und automake einzuarbeiten. Sie brauchen nur die Kommandozeilenoption --automake. Alles Weitere erledigt GNU Pascal f�r Sie! (Zum Zeitpunkt des Schreibens hat GNU Pascal einige kleinere Bugs im Zusammenhang mit der automake-Option. Diese Fehler werden aber nachgebessert. Au�erdem wird gerade an einem Utility namens gp gearbeitet, welches Ihnen noch mehr Arbeit beim Kompilieren abnimmt.)
Ein einfaches Makefile wie das folgende mag angebracht sein:
GPC_FLAGS=-O2
all: foo
foo: foo.pas unit1.pas
gpc --automake $(GPC_FLAGS) foo.pas
mostlyclean:
-rm -f *.o *.gpi *.gpd core
clean: mostlyclean
-rm -f foo
distclean: clean
extraclean: distclean
-rm -f *~*
maintainer-clean: extraclean
Sie wollen vielleicht dem Makefile noch weitere Regeln hinzuf�gen, sei es zur Erstellung der Dokumentation, Datendateien, Paketen zur Ver�ffentlichung oder zu was auch immer. Diese Dinge liegen au�erhalb des Rahmens dieses Textes. Die Kompilierung eines GNU Pascal Programmes erfolgt normalerweise mit gpc --automake.
Routinen sind Prozeduren (procedure), Funktionen (function), Objeckt-Konstruktoren (constructor) und -Destruktoren (destructor) sowie (selbstdefinierte) Operatoren.
Deklarationen sind diejenigen Bereiche des Programmes, die die Eigenschaften irgendwelcher Objekte “erkl�ren”, wie Konstanten, Typen, Variablen, Units, Module, und selbstverst�ndlich das Programm.
Anweisungen bzw. Statements sind solche Teile des Programmes, die irgendetwas “veranlassen”. Eine einzelne Anweisung ist eine Zuweisung (assignment), der Aufruf einer Prozedur (procedure call), ein Sprungbefehl (goto, Exit, Return, Break, Continue), eine Assembler-Anweisung oder eine zusammengesetzte Anweisung (begin ... end, if, case, repeat, while, for, with), die ihrerseits wieder verschiedene Anweisungen enthalten d�rfen.
Bezeichner (identifiers) sind Sprachelemente, die Objekten (Routinen, Konstanten, Variablen, Typen, Units oder Modulen) ihre Namen geben. Sie k�nnen lokal umdefiniert werden, anders als Schl�sselw�rter (keywords), die Teil einer festen Syntax sind (beispielsweise if ... then ... else) und nicht umdefiniert werden k�nnen. Makros sind keine Sprachelemente, da sie niemals vom Compiler verarbeitet werden, sondern von einem Pr�prozessor.
Endianess ist ein Begriff, der sich auf die Reihenfolge der Anordnung der h�her- und niederwertigen Bytes bezieht. Diese Reihenfolge ist auf manchen Systeme anders als auf anderen. Schauen Sie sich bitte die Erkl�rung dazu im GPC-Info Dokument an (see Endianness (gpc)).
Hinweis: Andere Begriffe k�nnen hier eingef�gt werden, sobald es sinnvoll erscheint. Wenn Sie die Definition eines Ausdruckes wissen m�chten, so teilen Sie es uns bitte mit.
MemoryMap: MemoryMap|
|
Copyright © 1996-2005 GNU Pascal development team
Verbatim copying and distribution is permitted in any medium, provided that this notice and the disclaimer below are preserved.
This information is provided in the hope that it will be useful, but without any warranty. We disclaim any liability for the accuracy of this information.
We are not responsible for the contents of web pages referenced by this site.
Copyright © 1996-2005 GNU Pascal development team
Kopieren und Verbreitung in unver�nderter Form in beliebigen Medien ist erlaubt, vorausgesetzt, dieser Hinweis und der Haftungsausschluss unten bleiben erhalten.
Diese Informationen werden in der Hoffnung, dass sie n�tzlich sind, verbreitet, aber ohne jede Gew�hrleistung. Wir schlie�en jede Haftung f�r die Zuverl�ssigkeit dieser Informationen aus.
Wir sind nicht verantwortlich f�r den Inhalt angelinkter Webseiten.