Dies ist ../p/doc/info/gpcs-de.info, hergestellt von Makeinfo Version
4.1 aus gpcs.texi.

START-INFO-DIR-ENTRY
* Pascal Coding Standards: (gpcs-de).   GNU Pascal Coding Standards (German).
END-INFO-DIR-ENTRY

   GNU Pascal Coding Standards

   Copyright (C) 2001-2003 Free Software Foundation, Inc.

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and without Back-Cover
Texts.

   A copy of the license is included in the section entitled
"Documentation Copying" in the GNU Pascal Manual.


File: gpcs-de.info,  Node: Top,  Next: Vorwort,  Up: (dir)

Version
*******

   Letzte Änderung 2003-01-01.  Basierend auf der englischen Version
von 2003-01-01.

* Menu:

* 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::


File: gpcs-de.info,  Node: Vorwort,  Next: Rechtliches,  Prev: Top,  Up: 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): 2003-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'.


File: gpcs-de.info,  Node: Rechtliches,  Next: Gestaltungsratschläge,  Prev: Vorwort,  Up: 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. *Note Intellectual Property: (standards)Intellectual
Property.


File: gpcs-de.info,  Node: Gestaltungsratschläge,  Next: Verhalten von Programmen,  Prev: Rechtliches,  Up: Top

Allgemeine Projektgestaltung
****************************

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

* Menu:

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


File: gpcs-de.info,  Node: Die Programmiersprache,  Next: Pascal und C,  Up: 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 (*note
Source Language: (standards)Source 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.


File: gpcs-de.info,  Node: Pascal und C,  Next: Erweiterungen benutzen,  Prev: Die Programmiersprache,  Up: 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 (*note Other Languages:
(gpc)Other 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 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.


File: gpcs-de.info,  Node: Erweiterungen benutzen,  Prev: Pascal und C,  Up: 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 *Note Glossar::, 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. (*note GPC Units: (GPC)GPC 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. *Note Using Extensions: (standards)Using Extensions.


File: gpcs-de.info,  Node: Verhalten von Programmen,  Next: Pascal Programmieren,  Prev: Gestaltungsratschläge,  Up: 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. *Note Program
Behavior: (standards)Program Behavior.

   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' (*note IOResult: (gpc)IOResult.) oder der
globalen Fehlervariablen wie `InOutRes' (*note InOutRes:
(gpc)InOutRes.). 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.


File: gpcs-de.info,  Node: Pascal Programmieren,  Next: Dokumentation,  Prev: Verhalten von Programmen,  Up: 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.

* Menu:

* Verschiedene Tips::           Verschiedene Tips zur Gestaltung
* Konsitenzüberprüfung::        Über die Benutzung von `Assert', um
                                abzubrechen, wenn etwas ``Unmögliches''
                                passiert.
* 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


File: gpcs-de.info,  Node: Verschiedene Tips,  Next: Konsitenzüberprüfung,  Up: 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: *Note 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. (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


File: gpcs-de.info,  Node: Konsitenzüberprüfung,  Next: Formatierung,  Prev: Verschiedene Tips,  Up: Pascal Programmieren

Explizite Überprüfung der internen Konsistenz
=============================================

   Wie in der GNU C-Bibliotheksdokumentation (*note Consistency
Checking: (libc)Consistency Checking.) 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 (*note Assert: (gpc)Assert.), den man z.B. mit der
`Trap'-Unit (*note Trap: (gpc)Trap.) abfangen kann.

   Wenn das Programm hinreichend getestet wurde, kann man die
Überprüfung von `Assert' abstellen, indem man das Programm mit der
Option `--no-assert' 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-assert'
nicht als Option angegeben wurde.

   Wir empfehlen, die Konsistenzüberprüfung nie abzuschalten, sofern
man den kleinen Laufzeitzuwachs verschmerzen kann.


File: gpcs-de.info,  Node: Formatierung,  Next: Kommentare,  Prev: Konsitenzüberprüfung,  Up: 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.


File: gpcs-de.info,  Node: Kommentare,  Next: Reihenfolge,  Prev: Formatierung,  Up: 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 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.


File: gpcs-de.info,  Node: Reihenfolge,  Next: Großschreibung,  Prev: Kommentare,  Up: 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 (*note var: (gpc)var.). 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:

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


File: gpcs-de.info,  Node: Großschreibung,  Next: Compiler-Direktiven,  Prev: Reihenfolge,  Up: 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.

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


File: gpcs-de.info,  Node: Compiler-Direktiven,  Next: Zwischenraum,  Prev: Großschreibung,  Up: 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: (*note 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? (*note 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' (*note
attribute: (gpc)attribute.) deklariert werden:

     procedure KritischeRoutine; attribute (iocritical);

   `{$W-}' (keine Warnungen) sollte nur lokal genutzt werden und ein
"FIXME"-Kommentar (*note 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. (*note
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 `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:

     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}


File: gpcs-de.info,  Node: Zwischenraum,  Next: Zeilenumbrüche,  Prev: Compiler-Direktiven,  Up: 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
`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);


File: gpcs-de.info,  Node: Zeilenumbrüche,  Next: Strings,  Prev: Zwischenraum,  Up: 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;


File: gpcs-de.info,  Node: Strings,  Next: Internationalisierung,  Prev: Zeilenumbrüche,  Up: 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: *Note Errors:
(standards)Errors.

   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.


File: gpcs-de.info,  Node: Internationalisierung,  Next: MemoryMap,  Prev: Strings,  Up: Pascal Programmieren

Techniken zur Internationalisierung
===================================

   Bitte beachten Sie die entsprechende Beschreibung in der
GPC-Dokumentation (*note I18N: (gpc)I18N.).


File: gpcs-de.info,  Node: MemoryMap,  Prev: Internationalisierung,  Up: 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.  *Note Mmap: (standards)Mmap.


File: gpcs-de.info,  Node: Dokumentation,  Next: Veröffentlichungen,  Prev: Pascal Programmieren,  Up: Top

Programme dokumentieren
***********************

   Wir empfehlen Ihnen, das entsprechende Kapitel der GNU Coding
Standards zu lesen *Note Documentation: (standards)Documentation, 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!


File: gpcs-de.info,  Node: Veröffentlichungen,  Next: Glossar,  Prev: Dokumentation,  Up: 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.  *Note Managing Releases: (standards)Managing Releases.

* Menu:

* Makefile-Regeln::           Wie man Makefiles schreibt


File: gpcs-de.info,  Node: Makefile-Regeln,  Up: 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 *.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'.


File: gpcs-de.info,  Node: Glossar,  Next: Index,  Prev: Veröffentlichungen,  Up: 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 (*note
Endianness: (gpc)Endianness.).

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


File: gpcs-de.info,  Node: Index,  Prev: Glossar,  Up: Top

Index
*****

* Menu:

* Abstand, Einrückung:                   Zwischenraum.
* Assert:                                Konsitenzüberprüfung.
* 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.
* 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.
* Konsitenzüberprüfung:                  Konsitenzüberprüfung.
* 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.



Tag Table:
Node: Top702
Node: Vorwort1395
Node: Rechtliches4167
Node: Gestaltungsratschläge4545
Node: Die Programmiersprache5064
Node: Pascal und C5870
Node: Erweiterungen benutzen8672
Node: Verhalten von Programmen13989
Node: Pascal Programmieren18045
Node: Verschiedene Tips19629
Node: Konsitenzüberprüfung25933
Node: Formatierung28344
Node: Kommentare31970
Node: Reihenfolge40056
Node: Großschreibung45013
Node: Compiler-Direktiven48899
Node: Zwischenraum59525
Node: Zeilenumbrüche64059
Node: Strings71953
Node: Internationalisierung73843
Node: MemoryMap74134
Node: Dokumentation74436
Node: Veröffentlichungen75927
Node: Makefile-Regeln76506
Node: Glossar77883
Node: Index79793

End Tag Table
