G

NU Pascal Coding Standards Copyright (C) 2001-2002 Frank Heckenbach `frank(at)pascal.gnu.de`, Peter Gerwinski `peter(at)gerwinski.de`, Nicola Girardi `nicola(at)g-n-u.de`

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.

Knoten:Top, Nächster:Vorwort, Aufwärts:(dir)

# Version

Verändert 10. Mai 2002. Basierend auf der englischen Version 10. Mai 2002.

- Vorwort: Über die GNU Pascal Coding Standards
- Rechtliches: Freie Software soll frei bleiben
- Gestaltungsratschläge: Allgemeine Projektgestaltung
- Verhalten von Programmen: Wie sich Programme verhalten sollten
- Pascal Programmieren: Ratschläge zur Gestaltung des Quelltextes
- Dokumentation: Programme dokumentieren
- Veröffentlichungen: Der Verlauf der Veröffentlichung
- Glossar: Glossar der Worte in diesem Text
- Index:

Knoten:Vorwort, Nächster:Rechtliches, Vorheriger:Top, Aufwärts:Top

# Über die GNU Pascal Coding Standards

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): 10. Mai 2002.

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`.

Knoten:Rechtliches, Nächster:Gestaltungsratschläge, Vorheriger:Vorwort, Aufwärts:Top

# Freie Software soll frei bleiben

Dieses Kapitel der GNU Coding Standards beschreibt unter anderem, wie man sich versichert, daß GNU Software rechtliche Schwierigkeiten vermeidet. SieheIntellectual Property.

Knoten:Gestaltungsratschläge, Nächster:Verhalten von Programmen, Vorheriger:Rechtliches, Aufwärts:Top

# Allgemeine Projektgestaltung

Dieses Kapitel beschäftigt sich mit einigen grundlegenden Themen zur Gestaltung eines Programmes.

- Die Programmiersprache: Welche Sprache nimmt man
- Pascal und C: Linken mit C Bibliotheken
- Erweiterungen benutzen: Das Benutzen von nicht standardisierten Erweiterungen

Knoten:Die Programmiersprache, Nächster:Pascal und C, Aufwärts:Gestaltungsratschläge

## Welche Sprache nimmt man

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 (sieheSource Language) 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.

Knoten:Pascal und C, Nächster:Erweiterungen benutzen, Vorheriger:Die Programmiersprache, Aufwärts:Gestaltungsratschläge

## Linken mit C Bibliotheken

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 (sieheOther Languages).

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 zu erhalten. 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.

Knoten:Erweiterungen benutzen, Vorheriger:Pascal und C, Aufwärts:Gestaltungsratschläge

## Das Benutzen von nicht standardisierten Erweiterungen

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:

- Kommentare der Form `(* *)` für alte Terminals, wo es die Zeichen `{` und `}` nicht gab.
- die `#`-Direktiven und `//`-Kommentare, wie in C/Delphi. Wenn eine Datei auch in C genutzt werden muß, so darf sie die `#`-Direktiven, die C-Syntax in Conditionalen sowie `//`-Kommentare enthalten. Gegenwärtig gibt es dazu folgende Beispiele (das kann sich in Zukunft ändern): `p/rts/constants.h` in den GNU Pascal Compiler Quellen und der untere Teil von `crt.inc`, welcher automatisch in `crt.h` kopiert wird.
- den Mißbrauch der typisierten Konstanten als Variablen, was eine seltsame Eigenschaft des Borland Pascal Compilers darstellt.
- Zeichen-Konstanten der Form `^A`. Benutzen Sie bitte `#1` oder `Chr (1)` stattdessen.
- `CString`s (außer natürlich für C-Schnittstellen)
- komplizierten Borland Pascal Code wie den folgenden anstelle von `WriteStr`:

      Str (Foo, s);
      s := 'Hallo ' + s;

- die meisten Fälle von `FillChar` und `Move`, außer für Low-Level-Programmierung und wenn es sich auf Zeichen innerhalb eines Strings bezieht. Das Benutzen von

      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 meisten Fälle von `GetMem` und `FreeMem`, die normalerweise ein Work-Around für fehlende Schemata in anderen Compilern sind.
- die meisten Fälle untypisierter Parameter.
- die meisten selbstgemachten dateinamenbezogenen Routinen. (Falls sie in Borland Pascal geschrieben wurden, so sind sie zumeist sowieso nur unter DOS anwendbar. Benutzen Sie die Möglichkeiten der `GPC`-Unit, um einen portablen Weg einzuschlagen.)
- Assembler-Code. Außer natürlich in seltenen Fällen, wo es um die Optimierung von Code geht. Dort sollte er mit Hilfe von `{$ifdef}` (z.B. für den Prozessortyp) eingekapselt werden. Unterstützen Sie in einem solchen Fall auch bitte eine reine Pascal-Version dieser Routinen innerhalb des `{$else}`-Teiles. Testen Sie diese Routinen.
- alles, was die `System`-Unit erfordert.
- Annahmen über Typengrößen.
- Annahmen über "Endianness". (Einige Systeme verwenden für die Anordnung von höher- und niederwertige Bytes eine andere Reihenfolge als andere Systeme.) [Anm. d. Übersetzers: Die Begriffe "Little Endian" und "Big Endian" lassen sich leider nicht direkt übersetzen. Schauen Sie ins Glossar SieheGlossar, um mehr über diese Begriffe herauszufinden.]
- Bezeichner, die mit einem oder mehreren Unterstrichen (`_`) beginnen oder enden.
- Units, die nur zur Kompatibilität mit Borland Pascal geschrieben wurden. (sieheGPC Units) Die Units `CRT` und `Printer` hingegen dienen sowohl der Kompatibilität zu Borland Pascal als auch dem allgemeinen Nutzen.

Die GNU Coding Standards haben interessante Anmerkungen zu diesem Thema. SieheUsing Extensions.

Knoten:Verhalten von Programmen, Nächster:Pascal Programmieren, Vorheriger:Gestaltungsratschläge, Aufwärts:Top

# Wie sich Programme verhalten sollten

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. SieheProgram Behavior.

Einige Hinweise zur Pascal Programmierung:

Die in den GNU Coding Standards besprochene Auswahl 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` (sieheIOResult) oder der globalen Fehlervariablen wie `InOutRes` (sieheInOutRes). 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. In Zukunft werden Namenskonflikte durch qualifizierte Bezeichner (`UnitName.RoutinenName`) gelöst. Bitte benutzen Sie bis dahin bei Namenskonflikten vorübergehend Work-Arounds.

Knoten:Pascal Programmieren, Nächster:Dokumentation, Vorheriger:Verhalten von Programmen, Aufwärts:Top

# Ratschläge zur Gestaltung des Quelltextes

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.

- Verschiedene Tips: Verschiedene Tips zur Gestaltung
- Formatierung: Wie man die Quellen formatiert
- Kommentare: Quellen kommentieren
- Reihenfolge: Reihenfolge der Code-Bereiche
- Großschreibung: Großschreibung
- Compiler-Direktiven: Benutzung von Compiler-Direktiven
- Zwischenraum: Wie man Leerzeichen in Code benutzt
- Zeilenumbrüche: Wo man seine Zeilen umbrechen sollte
- Strings: Zeichenketten
- Internationalisierung: Techniken zur Internationalisierung
- MemoryMap: Wie Sie sicher `MemoryMap` benutzen

Knoten:Verschiedene Tips, Nächster:Formatierung, Aufwärts:Pascal Programmieren

## Verschiedene Tips zur Gestaltung

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. Zwar erlaubt der GNU Pascal Compiler mehrere Units etc. pro Datei, doch wird diese Möglichkeit in Zukunft möglicherweise verworfen.

Der Code sollte mit der Option `-Wall`, sowohl mit als auch ohne `-O2` kompilierbar sein und in keinem Fall irgendwelche Warnungen ergeben. (Siehe: SieheCompiler-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. (Diese Technik wird Ihnen in einer zukünftigen Version des GNU Pascal Compilers zur Verfügung gestellt werden und heißt "qualifizierte Bezeichner", aber auch dann raten wir von der Verwendung ab.)

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

Knoten:Formatierung, Nächster:Kommentare, Vorheriger:Verschiedene Tips, Aufwärts:Pascal Programmieren

## Wie man die Quellen formatiert

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.

Knoten:Kommentare, Nächster:Reihenfolge, Vorheriger:Formatierung, Aufwärts:Pascal Programmieren

## Quellen kommentieren

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. }
      ...

    begin
      { Mein erstes Statement. }
      Bla;
      { Anfang der Schleife. }
      repeat
        { Schleifenkörper. }
        ...
      { Beende das hier mal irgendwann. }
      until Sometime
    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 Konstanten-Deklarationen 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.

Knoten:Reihenfolge, Nächster:Großschreibung, Vorheriger:Kommentare, Aufwärts:Pascal Programmieren

## Reihenfolge der Code Bereiche

Jede Datei sollte mit einem Kommentar beginnen, welcher der Reihe nach folgendes beinhaltet:

- eine kurze Beschreibung, was der Code in dieser Datei macht
- eine längere Beschreibung über Details des Codes und wo man sich informieren kann
- Copyright-Informationen (Autoren)
- Die Lizenz (Klar, Sie wollen immer die GNU General Public License oder die Lesser General Public License nutzen!)

Allgemein sollte man diese Deklarations-Reihenfolge einhalten:

- `const`-Deklarationen
- `type`-Deklarationen
- `var`-Deklarationen
- `label`-Deklarationen
- Routinen

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 (siehevar). 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 (16);
      TBar = Cardinal (16);
      TBaz = Cardinal (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:

- Felder
- Konstruktoren
- Destruktoren (hiervon sollte es nur einen geben)
- Methoden

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.

Knoten:Großschreibung, Nächster:Compiler-Direktiven, Vorheriger:Reihenfolge, Aufwärts:Pascal Programmieren

## Großschreibung

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.

`c` und `c_language` sind gegenwärtig Direktiven, wobei sie in naher Zukunft verschwinden. In der Zwischenzeit wird `C` auch akzeptiert.

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.

Beachten Sie, daß `asmname` eine Direktive ist, daher sollte sie nicht als `AsmName` geschrieben werden. 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).

Knoten:Compiler-Direktiven, Nächster:Zwischenraum, Vorheriger:Großschreibung, Aufwärts:Pascal Programmieren

## Benutzung von Compiler-Direktiven

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: (sieheKommentare)

    (*$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? (sieheGroß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 (Routinen, die Ein-/Ausgabe-Fehler hervorrufen können, sollten als `iocritical` deklariert werden, sobald dies verfügbar wird). Für Programme ist dies optional.

`{$W-}` (keine Warnungen) sollte nur lokal genutzt werden und ein "FIXME"-Kommentar (sieheKommentare) haben, denn es zeigt ein Problem mit dem Code oder dem Compiler. Benutzen Sie spezielle Direktiven, um Warnungen über Compiler-Probleme bei Bedarf auszuschalten. Beispielsweise, `{$W no-object-directives}` oder `{$W no-field-name-problem}`. Die Abschaltung dieser speziellen Warnungen kann global erfolgen.

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 `ignorable` deklarieren, sobald dieses Feature verfügbar wird, so daß das Funktionsergebnis ignoriert werden kann. Im Moment sollten Sie noch Dummy-Variablen benutzen.

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. (sieheCompiler-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 `define`s 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 `define`s einsetzen. Folgendes ist ein Beispiel aus der CRT-Unit:

    TWindowXY = packed record
      {$ifdef __BYTES_BIG_ENDIAN__}
      Fill: Integer (BitSizeOf (Word) - 16);
      Y, X: Word (8)
      {$else}
      X, Y: Word (8);
      Fill: Integer (BitSizeOf (Word) - 16)
      {$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__ < 20011123}
    {$error This unit requires GPC release 20011123 or newer.}
    {$endif}

Knoten:Zwischenraum, Nächster:Zeilenumbrüche, Vorheriger:Compiler-Direktiven, Aufwärts:Pascal Programmieren

## Wie man Leerzeichen in Code benutzt.

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 nicht `Foo [42]`, sondern `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);

Knoten:Zeilenumbrüche, Nächster:Strings, Vorheriger:Zwischenraum, Aufwärts:Pascal Programmieren

## Wo man seine Zeilen umbrechen sollte

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;

Knoten:Strings, Nächster:Internationalisierung, Vorheriger:Zeilenumbrüche, Aufwärts:Pascal Programmieren

## Zeichenketten

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: SieheErrors.

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.

Knoten:Internationalisierung, Nächster:MemoryMap, Vorheriger:Strings, Aufwärts:Pascal Programmieren

## Techniken zur Internationalisierung

SieheConcepts, für allgemeine Informationen bzgl. Internationalisierung und Lokalisierung.

Ein Tool zur Internationalisierung, welches ähnlich wie `xgettext` arbeitet und `pas2po` heißt, wird Ihnen unter folgender URL angeboten: http://www.gnu-pascal.de/contrib/eike/ In diesem Zusammenhang möchten wir Sie auch auf die `inter`-Unit hinweisen, welche Sie an selbiger Stelle finden können. Sie benötigen sowohl `pas2po` als auch die Unit, um Ihr Programm zu internationalisieren. Bitte lesen Sie die den Paketen beigefügten Informationen.

Knoten:MemoryMap, Vorheriger:Internationalisierung, Aufwärts:Pascal Programmieren

## MemoryMap

Dieser Abschnitt der GNU Coding Standards kann so, wie er ist, auf GNU Pascal übertragen werden. Beachten Sie, daß `mmap` hier `MemoryMap` bedeutet. SieheMmap.

Knoten:Dokumentation, Nächster:Veröffentlichungen, Vorheriger:Pascal Programmieren, Aufwärts:Top

# Programme dokumentieren

Wir empfehlen Ihnen, das entsprechende Kapitel der GNU Coding Standards zu lesen SieheDocumentation, 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`-Option 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 selbstverständlich entweder im Quelltext oder 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!

Knoten:Veröffentlichungen, Nächster:Glossar, Vorheriger:Dokumentation, Aufwärts:Top

# Der Verlauf der Veröffentlichung

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. SieheManaging Releases.

- Makefile-Regeln: Wie man Makefiles schreibt

Knoten:Makefile-Regeln, Aufwärts:Veröffentlichungen

## Wie man Makefiles schreibt

Für Ihre Pascal-Projekte benötigen Sie keine großen `Makefile`s 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 *.gpm 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`.

Knoten:Glossar, Nächster:Index, Vorheriger:Veröffentlichungen, Aufwärts:Top

# Glossar der Worte in diesem Text

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 (sieheEndianness).

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.

Knoten:Index, Vorheriger:Glossar, Aufwärts:Top

# Index

- Abstand, Einrückung: Zwischenraum
- Aufzählungstypen: Großschreibung
- Auskommentieren: Kommentare
- Auskommentieren von Code: Compiler-Direktiven
- Bedingte Kompilierung: Compiler-Direktiven
- Beiträge zum Dokument: Vorwort
- Beschreibende Kommentare: Kommentare
- Blanks: Formatierung
- Blanks bei Direktiven: Compiler-Direktiven
- Boolean: Verschiedene Tips
- Boolsche Werte: Verschiedene Tips
- C-Code Compilation: Pascal und C
- Case und der Zeilenumbruch: Zeilenumbrüche
- Compiler-Direktiven: Compiler-Direktiven
- Conditionale und GPC-Versionen: Compiler-Direktiven
- Conditionale und Implementationsverwaltung: Compiler-Direktiven
- Conditionale und Versionsverwaltung: Compiler-Direktiven
- Debug-Flag: Compiler-Direktiven
- declaration blocks: Reihenfolge
- Deklarationen innerhalb eines Typ-Deklarations-Blocks: Reihenfolge
- Deklarationen innerhalb von Objekttypen: Reihenfolge
- dokumentieren: Dokumentation
- Download der Coding Standards: Vorwort
- Dumme Kommentare: Kommentare
- Einrückung: Zeilenumbrüche
- Einrückung von Labeln: Zeilenumbrüche
- Einrückung, Abstand: Zwischenraum
- Feedback: Vorwort
- Fehlerabfragen: Verhalten von Programmen
- Fixme Kommentare: Kommentare
- Formatierung: Formatierung
- `gettext`: Internationalisierung
- Globale Variablen: Verschiedene Tips
- Glossar: Glossar
- Großschreibung: Großschreibung
- Großschreibung von Bezeichnern: Großschreibung
- Großschreibung von Konstanten: Großschreibung
- Großschreibung von Makros: Großschreibung
- Header-Übersetzung: Pascal und C
- if then else Anweisungen und Zeilenumbrüche: Zeilenumbrüche
- Internationalisierung: Internationalisierung
- Kommentare: Kommentare
- Kommentare bei nicht naheliegendem Code: Kommentare
- Kommentare mit Textauszeichnung: Kommentare
- Kommentare und Direktiven: Compiler-Direktiven
- Kommentare zu externen Quellen: Kommentare
- Kommentare zur Trennung logischer Abschnitte: Kommentare
- Kommentarraster: Kommentare
- Komplizierte Conditionale: Compiler-Direktiven
- Konstanten: Großschreibung
- Leerzeichen: Formatierung
- Leerzeilen: Formatierung
- legal aspects: Rechtliches
- Linken mit C Bibliotheken: Pascal und C
- Linker-Direktiven: Compiler-Direktiven
- Lokale Direktiven: Compiler-Direktiven
- Makefile-Regeln: Makefile-Regeln
- `MemoryMap`: MemoryMap
- Nicht-Standard Erweiterungen: Erweiterungen benutzen
- no-warning Direktive: Compiler-Direktiven
- OOP: Großschreibung
- Pascal und C: Pascal und C
- Plazierung der Kommentare: Kommentare
- Programmiersprache: Die Programmiersprache
- Projektgestaltung: Gestaltungsratschläge
- Reihenfolge: Reihenfolge
- Reihenfolge der Implementation: Reihenfolge
- Schleifen: Zeilenumbrüche
- Signal-Funktionen: Verhalten von Programmen
- Sprache in Kommentaren: Kommentare
- Standard-Direktiven: Compiler-Direktiven
- Steuerzeichen: Formatierung
- Strings: Strings
- Testen der Rückgabewerte: Compiler-Direktiven
- Trickreiche Kommentare: Kommentare
- Triviale Kommentare: Kommentare
- Umbruch langer Zeilen: Zeilenumbrüche
- Unendliche Schleifen: Verschiedene Tips
- Variablen-Deklaration: Reihenfolge
- Verschachtelte Kommentare: Kommentare
- Verschiedene Tips: Verschiedene Tips
- Veröffentlichung des Programmes: Veröffentlichungen
- Wo man die GPCS findet: Vorwort
- Wrapper: Pascal und C
- Zeichenketten: Strings
- Zeilenlänge: Formatierung
- Zeilenumbrüche: Zeilenumbrüche

# Inhaltsverzeichnis

- Version
- Über die GNU Pascal Coding Standards
- Freie Software soll frei bleiben
- Allgemeine Projektgestaltung
  - Welche Sprache nimmt man
  - Linken mit C Bibliotheken
  - Das Benutzen von nicht standardisierten Erweiterungen
- Wie sich Programme verhalten sollten
- Ratschläge zur Gestaltung des Quelltextes
  - Verschiedene Tips zur Gestaltung
  - Wie man die Quellen formatiert
  - Quellen kommentieren
  - Reihenfolge der Code Bereiche
  - Großschreibung
  - Benutzung von Compiler-Direktiven
  - Wie man Leerzeichen in Code benutzt.
  - Wo man seine Zeilen umbrechen sollte
  - Zeichenketten
  - Techniken zur Internationalisierung
  - MemoryMap
- Programme dokumentieren
- Der Verlauf der Veröffentlichung
  - Wie man Makefiles schreibt
- Glossar der Worte in diesem Text
- Index