\section{Der Compiler}

\subsection{Arbeitsweise des Compilers}

Die Aufgabe des Compilers ist die "Ubersetzung eines f"ur den
Menschen lesbaren Quelltextes in einen maschinenn"aheren
Code gleicher Bedeutung. Diese recht einfache Erkl"arung
beinhaltet aber nicht den Umfang dieser Aufgabe. Die "Ubersetzung
eines Quelltextes muss in mehrere Teilaufgaben gegliedert werden.
Zun"achst m"ussen die Symbole erkannt, danach die Syntax kontrolliert,
darauf die internen Tabellen f"ur die verwendeten Strukturen generiert,
die Typenkontrolle durchgef"uhrt und schliesslich der Code
erzeugt werden. F"ur ein Fehlerprotokoll ist unter Umst"anden
ein weiterer Durchgang n"otig. Erstaunlicherweise ist "ubrigens
das Weiterlaufen nach einem Fehler eine der schwierigsten
Aufgaben des Compilerbauers. Auch sollte der Compiler
so absturzsicher wie m"oglich sein.

Ein {\bf Mehrpasscompiler} f"uhrt jeden Arbeitsgang f"ur sich und
einer nach dem anderen aus.
Dazu m"ussen Zwischendateien erzeugt und von jedem Durchgang
wieder gelesen werden. Dies f"uhrt zu einer langsamen
Compilation und, falls im Hauptspeicher zwischengespeichert
wird, zu einem erh"ohten Speicherbedarf.

Ein {\bf Einpasscompiler} f"uhrt diese Arbeitsg"ange parallel aus.
Jedes Programmelement, dessen Struktur erkannt wird,
wird sofort in Code umgewandelt. Ein Einpasscompiler wird dadurch
extrem schnell, ohne dass dem Programmierer Nachteile
erwachsen.\footnote{Die Nachteile des im Fehlerfall
unn"otigerweise erzeugten Codes werden durch den im
allgemeinen erreichten Zeitgewinn wettgemacht}
Einzig alle referenzierten Objekte m"ussen vor dem Gebrauch
deklariert sein.

Der Amiga \mtwo-Compiler ist ein Einpasscompiler. Der erzeugte Code
ist Maschinencode des MC68000, je nach Prozessortyp erweitert
um die speziellen F"ahigkeiten. Dies bewirkt sehr schnelle
Programme. Als Beispiel diene der Compiler selbst, der ebenfalls
in \mtwo\ programmiert wurde.

Die Quelldateien sind normale {\bf Textdateien}. Wird ein Definitionsmodul
compiliert, erzeugt der Compiler eine {\bf Symboldatei}. Aus
Imp\-le\-men\-ta\-tions- oder Programm-Moduln entstehen
{\bf Objektdateien} (Abbildungen \ref{def-umgebung} und \ref{mod-umgebung}).

Eine Symboldatei dient als Referenz bei einem Import
dieses Moduls. Es handelt sich um eine "ubersetzte Version
der Schnittstelle. Um eine vollst"andige Typen- und Versions-Kontrolle
zu erm"oglichen, ist ein eindeutiger Schl"ussel\footnote{Der
Schl"ussel wird aus dem Zeitpunkt der Compilation abgeleitet}
abgelegt. Importiert
ein Modul ein anderes Modul, so wird f"ur die Compilation
dessen Symboldatei gelesen. Dies erm"oglicht eine
vollst"andige Typenkontrolle.

\begin{figure}
\begin{center}
\unitlength1cm
\begin{picture}(8,3)
\put(4,0.7){\oval(2.0,1.4)} \put(3,0){\makebox(2.0,1.4){\tt m2c}}
\put(2,0.7){\vector(1,0){1}}
  \put(2.6,1){\makebox(0,0)[rb]{\cmsltt Modul\/\tt.def}}
\put(5,0.7){\vector(1,0){1}}
  \put(5.4,1){\makebox(0,0)[lb]{\cmsltt Modul\/\tt.sym}}
\put(4,1.5){\line(2,1){0.6}}
  \put(4.6,1.8){\line(-1,0){0.3}}
  \put(4.3,1.8){\line(0,1){0.4}}
\put(4,1.5){\line(-2,1){0.6}}
  \put(3.4,1.8){\line(1,0){0.3}}
  \put(3.7,1.8){\line(0,1){0.4}}
\put(3.7,2.2){\line(1,0){0.6}}
\put(4,2.4){\makebox(0,0)[b]{{\tt sym}-Dateien}}
\end{picture}
\caption{\label{def-umgebung}Umgebung f\protect"ur Definitionsmoduln}
\end{center}
\end{figure}

Objektdateien aus Implementationsmoduln oder aus
Progra"mmoduln werden "ahnlich behandelt. Bei
Implementationsmoduln wird kontrolliert, ob alle in
der Definition vermerkten Prozeduren auch implementiert
sind. Ebenfalls wird die Gleichheit des Prozedurkopfs
in Definition und Implementation gepr"uft. Die Schl"ussel
aller importierten Moduln werden vermerkt. So kann
beim nachfolgenden Linkvorgang kontrolliert werden,
ob die Definition eines importierten Moduls nicht
zwischenzeitlich ge"andert wurde.

\begin{figure}
\begin{center}
\unitlength1cm
\begin{picture}(8,3)
\put(4,0.7){\oval(2.0,1.4)} \put(3,0){\makebox(2.0,1.4){\tt m2c}}
\put(2,0.7){\vector(1,0){1}}
  \put(2.6,1){\makebox(0,0)[rb]{\cmsltt Modul\/\tt.mod}}
\put(5,0.7){\vector(1,0){1}}
  \put(5.4,1){\makebox(0,0)[lb]{\cmsltt Modul\/\tt.obj}}
\put(5,0.5){\line(1,0){0.8}} \put(5.8,0.5){\vector(0,-1){0.4}}
  \put(5.9,0.1){\makebox(0,0.4)[l]{\cmsltt Modul\/\tt.ref}}
\put(4,1.5){\line(2,1){0.6}}
  \put(4.6,1.8){\line(-1,0){0.3}}
  \put(4.3,1.8){\line(0,1){0.4}}
\put(4,1.5){\line(-2,1){0.6}}
  \put(3.4,1.8){\line(1,0){0.3}}
  \put(3.7,1.8){\line(0,1){0.4}}
\put(3.7,2.2){\line(1,0){0.6}}
\put(4,2.4){\makebox(0,0)[b]{{\tt sym}-Dateien}}
\end{picture}
\caption{\label{mod-umgebung}Umgebung f\protect"ur
  Implementations- oder Programm-Moduln}
\end{center}
\end{figure}

Zu jeder Objektdatei wird auch eine sogenannte {\bf Referenzdatei}
erzeugt. Die Referenzdatei enth"alt Informationen, die
in erster Linie vom Debugger ben"otigt werden.
Ausserdem greifen Profiler, Library-Linker und Dekodier-Programme 
darauf zu.
F"ur die Compilation und den Linkvorgang haben
die Referenzdateien keine Bedeutung.

Wird w"ahrend der Compilation ein Fehler in der Quelldatei gefunden,
bricht die "Ubersetzung {\em nicht\/} ab. Es wird versucht, mit
vern"unftigen Annahmen weiter zu "ubersetzen. So k"onnen mehrere
Fehler des Quelltextes in {\em einem\/} "Ubersetzungsvorgang
gefunden werden. Nicht m"oglich ist dies allerdings, wenn ein
Modul, das in einer Import-Liste verlangt wird, nicht gefunden wird;
dann bricht die Compilation ab.

Alle gefundenen Fehler bis zu einem Maximum von 150 Fehlern
werden in einer vom Compiler
erzeugten {\bf Fehlerdatei} festgehalten. Die Fehlerdatei hat den Namen der
Eingabedatei, erweitert um den Buchstaben "`{\tt E}"'.
Wird beispielsweise das Modul "`{\tt InOut.mod}"' "ubersetzt,
so erzeugt der Compiler eine Datei "`{\tt InOut.modE}"'im gleichen
Verzeichnis. Die Fehlerdatei wird dann vom Editor oder vom
Fehlerlister eingelesen, um alle Fehler im Klartext anzuzeigen.

\subsection{Compiler-Optionen}

\label{refOptions}
Mit Hilfe von Optionen l"asst sich die Arbeitsweise des Compilers
steuern. Die meisten dieser Optionen dienen lediglich dazu,
die Erzeugung von "Uberpr"ufungscode f"ur Laufzeitfehler ein- oder
auszuschalten. Das Programm ist auf jeden Fall ablauf"|f"ahig,
nur mit unterschiedlicher
Sicherheit, Geschwindigkeit und Gr"osse. Andere Optionen hingegen sind sehr
wichtig, um ein Programm korrekt ablaufen zu lassen. Die Optionen
sind als interne Variablen vom Typ {\tt BOOLEAN} realisiert. Die einzelnen
Optionen werden im folgenden genau erl"autert.

Der Zustand einiger Optionen l"asst sich nur von der Kommandozeile,
derjenige
anderer Optionen nur im Quelltext "andern.
Der verbleibende Rest der Optionen kann an beiden Orten ge"andert
und gesetzt werden.

Die Steuerung der einzelnen Optionen erfolgt beim Aufruf
des Compilers oder interaktiv mit einem "`{\tt -}"' oder "`{\tt +}"'.
Mit dem 
zugeh"origen Buchstaben werden die Optionen auf den Wahrheitswert "`falsch"'
beziehungsweise "`wahr"' gesetzt (siehe \ref{refBedien},
Programmaufruf und -Bedienung).

\subsubsection{Wirkungs- und Ver\protect"anderungs-Bereiche}

Jede Option hat zu Beginn einer Compilationseinheit einen {\bf Vorgabewert}.
Dieser Wert wird beim Aufruf des Compilers von ihm eingestellt, kann jedoch
von der Kommandozeile oder interaktiv vom Bediener ver"andert werden.
W"ahrend der Compilation kann der Zustand von Optionen innerhalb des Quelltextes
ver"andert werden. Er gilt dann --- von einigen Ausnahmen abgesehen --- bis zur
n"achsten "Anderung im Quelltext. Nach der Compilation werden alle Optionen
wieder auf ihren vom Compiler oder Bediener eingestellten Vorgabewert
gesetzt, so dass die n"achste Compilation mit den gleichen Bedingungen
abl"auft.

W"ahrend der Compilation k"onnen gewisse Optionen vom Compiler
"`{\bf eingefroren}"' werden. Dies bedeutet, eine Ver"anderung ist nach dieser
Stelle im Quelltext nicht erlaubt, bis der Compiler die Option
wieder freigibt. Eine dennoch versuchte "Anderung erzeugt eine Fehlermeldung.

Einige Optionen m"ussen f"ur eine ganze Compilationseinheit den gleichen
Wert besitzen. Sie werden nach dem Modulkopf eingefroren und nicht wieder
freigegegeben. Das Setzen oder Ver"andern dieser Optionen ist nur bis
zum Beginn der {\tt IMPORT}-Liste oder der ersten Deklaration erlaubt.
Wir nennen dies im folgenden {\bf pro Modul\/} oder {\bf modulbezogen}.

Andere Optionen m"ussen innerhalb einer Prozedur oder eines Moduls gleich
bleiben. Sie
werden bei der {\tt BEGIN}-Anweisung der Prozedur 
eingefroren und bei der zugeh"origen {\tt END}-Anweisung
der
Prozedur wieder freigegeben. Hat eine Prozedur keine
{\tt BEGIN}-Anweisung, so fallen das Einfrieren und Freigeben zusammen.

\noindent
Die Optionen teilen sich in zwei Gruppen:
\begin{description}
\item[stapelbar] bedeutet, dass diese Option an jeder beliebigen Stelle
   im Quelltext gesetzt oder gel"oscht werden darf. Der alte Wert wird
   intern in einem Stapel vermerkt.
   Er kann auch wieder vom Stapel geholt werden. Eine "Anderung darf nur
   erfolgen, wenn die Option nicht eingefroren ist.
\item[bereichsbezogen] sind Optionen, die nur f"ur einen bestimmten
Bereich g"ultig sind, im Normalfall eine Prozedur. Sie d"urfen nicht
beliebig ver"andert, sondern nur f"ur die n"achste Prozedur
  auf das Gegenteil ihres Vorgabewertes gesetzt werden.
  Das Holen vom Stapel oder das Setzen auf den Vorgabewert f"uhrt zu
  einer Fehlermeldung.  Die Wirkung erstreckt sich "uber diese Prozedur
  und der Wert wird danach wieder automatisch mit dem Vorgabewert besetzt.

\begin{example}
Zum Beispiel hat die bereichsbezogene Option {\tt LoadA4}
den Vorgabewert {\tt FALSE},
darf also nur auf {\tt TRUE} gesetzt werden.
\begin{verbatim}
  PROCEDURE Handler;
  (*$ LoadA4:=TRUE *)
  BEGIN
  ...
  END Handler;
\end{verbatim}
Die Option hat im Normalfall den Wert {\tt FALSE},
innerhalb der Prozedur den Wert {\tt TRUE} und
wird danach automatisch wieder zu {\tt FALSE}.
\end{example}

\begin{warning}
Bei verschachtelten Prozeduren ist Vorsicht geboten! Der Ort der
Compiler-Anweisung muss genau "uberlegt sein. Beispielsweise wird
der folgende Programmtext nicht erreichen, was vom Programmierer
beabsichtigt war
und sp"ater zu einem Programm-Absturz f"uhren:

\begin{example}
\begin{verbatim}
(*$ LoadA4:=TRUE *) (* FALSCH!!! *)
PROCEDURE Handler;
  PROCEDURE Intern;
  END Intern;
BEGIN
  ...
END Handler;
\end{verbatim}
In diesem Fall wird die Prozedur {\tt Intern} {\em mit\/} der Option
{\tt LoadA4} "ubersetzt, die Prozedur {\tt Handler} jedoch {\em ohne\/},
auch wenn {\tt Intern} lokal ist und kein {\tt BEGIN} enth"alt! Richtig ist
vielmehr folgende Schreibweise:
\begin{verbatim}
PROCEDURE Handler;
  PROCEDURE Intern;
  END Intern;
(*$ LoadA4:=TRUE *) (* RICHTIG!! *)
BEGIN
END Handler;
\end{verbatim}
\end{example}
\end{warning}
\end{description}


\subsubsection{Compiler-Anweisungen im Quelltext}

Einige Optionen lassen sich mit Hilfe der {\bf Compiler-Anweisungen}
im Quelltext ver"andern. Die Compiler-Anweisung ist eine spezielle
Form eines Kommentars. Sie wird jedoch --- im Gegensatz zu Kommentaren ---
nicht "uberlesen, sondern vom Compiler ausgewertet. Die Syntax
ist
\begin{quote} \tt "(*\$"~\{\cmsltt Anweisung\/\tt\} "*)". \end{quote}
Zu Anfang muss also das Symbol "`\verb|(*$|"' stehen. Das \verb'$'-Zeichen darf
nicht durch Leerzeichen vom \verb|*| abgesetzt sein, andernfalls wird
der Bereich wie ein normaler Kommentar behandelt! Danach folgt eine
beliebige Anzahl von Anweisungen, die durch Leerzeichen oder Zeilenvorsch"ube
getrennt sind. Hier d"urfen {\em nur\/} Anweisungen auftreten, insbesondere
{\em keine Kommentare\/}! Die Compiler-Anweisung wird durch
 "`\verb|*)|"' beendet. Compiler-Anweisungen innerhalb von Kommentaren
 werden ignoriert.

Die Anweisungen zum Ver"andern von Optionen haben die Form
\begin{quote} \cmsltt Option \tt ":="~\cmsltt BoolescherAudruck.
\hfill\rm ({\it 1\/})\end{quote}
oder
\begin{quote} \tt \dq POP"~\cmsltt Option. \hfill\rm ({\it 2\/})\end{quote}
oder
\begin{quote} \tt "DEFINE"~\cmsltt Option \tt ":="~\cmsltt BoolescherAusdruck.
\hfill\rm ({\it 3\/})\end{quote}
"`{\cmsltt Option}"' ist hierbei ein vom Compiler vordefinierter
oder vom Benutzer
durch die "`{\tt DEFINE}"'-Anweisung definierter Name.
"`{\cmsltt BoolescherAusdruck}"' kann "`{\tt TRUE}"' oder "`{\tt FALSE}"', der
Name einer Option oder auch ein aus diesen Elementen durch "`{\tt NOT}"',
"`{\tt AND}"', "`{\tt OR}"' und Klammerung gebildeter Ausdruck sein.
Die Schl"usselw"orter ({\tt DEFINE}, {\tt POP}, {\tt FALSE},
\ldots) m"ussen {\em gross\/} geschrieben
werden. Die Namen der Optionen k"onnen beliebig gross oder klein geschrieben
sein.

Die {\bf Zuweisung} ({\it 1\/}) setzt eine "`{\bf Options-Variable}"'
auf den durch den
Ausdruck bestimmten Wert und merkt sich den alten Zustand dieser Option
auf einem Stapel, der bis zu 32 Werte aufnehmen kann. Wenn mehr als
32 Zuweisungen in Folge auftreten, erfolgt {\em keine\/} Fehlermeldung.

\begin{verbatim}
(*$ StackChk:=FALSE *)
\end{verbatim}

Die "`{\tt POP}"'-Anweisung ({\it 2\/}) holt den Wert
der Option vom zugeh"origen Stapel.
Wenn zuvor keine Zuweisung erfolgt ist, bekommt sie den eingestellten
Vorgabewert. Dies ist auch der Fall, falls mehr als
32 "`{\tt POP}"'-Anweisungen in Folge auftreten sollten.
Sie kann im Zusammenwirken mit
der Zuweisung dazu benutzt
werden, begrenzte Bereiche mit einem bestimmten Wert einer 
Option zu kompilieren, ohne
f"ur die nachfolgenden Bereiche den voreingestellten Wert der
Option zu ver"andern.

\begin{example}
\begin{verbatim}
(*$ POP StackChk *)
\end{verbatim}
\end{example}

Die "`{\bf DEFINE}"'-Anweisung ({\it 3\/})
definiert eine neue Benutzer-Option. Der
Name der Option darf kein vom Compiler vordefinierter Name sein.
Auch darf kein Name mehrmals in einem Quelltext  definiert 
werden. Gross- und Kleinschreibung spielen
hierbei keine Rolle.

Benutzerdefinierte Optionen k"onnen von der Kommandozeile mit
einem Vorgabewert belegt werden. Dies geschieht durch die
Anweisung "`{\tt -oName}"' oder "`{\tt +oName}"'. Hierdurch
wird eine {\em potentielle\/} be\-nut\-zer\-de\-fi\-nier\-te Option erzeugt
und mit dem Vorgabewert {\tt FALSE} beziehungsweise {\tt TRUE}
belegt.
Der Name der Option ist jedoch im Quelltext zun"achst unbekannt,
nur eine "`{\tt DEFINE}"'-Anweisung kann ihn sicht\-bar machen.

\begin{example}
\begin{verbatim}
(*$ DEFINE Demo:=FALSE *)
\end{verbatim}
\end{example}

Hier gilt es zwei F"alle zu unterscheiden:
\begin{itemize}
\item  Die "`{\tt DEFINE}"'-Anweisung definiert einen Namen, der vom Bediener
{\em nicht\/} definiert wurde. Die neue Option erh"alt den im
Quelltext angegebenen Wert. Der Compiler gibt nach obigem Beispiel
folgende Meldung auf dem Bildschirm aus:
\begin{verbatim}
!! DEFINE: -DEMO
\end{verbatim}
\item  Die "`{\tt DEFINE}"'-Anweisung definiert einen Namen, der bereits von
der Kommandozeile bekannt ist. Die neue Option erh"alt den vom Bediener
angegebenen Wert, ˆder im Quelltext angegebene wird ignoriert. Ausgabe
des Compilers auf dem Bildschirm:
\begin{verbatim}
!! DEFINE: -DEMO (Wert wird ignoriert, bleibt "+")
\end{verbatim}
\end{itemize}

\begin{note} Es gibt noch weitere Anweisungen, die bei der bedingten
Kompilierung eine Rolle spielen (Abschnitt \ref{refCondComp}, Seite
\pageref{refCondComp}). Haupts"achlich daf"ur wurde auch die
"`{\tt DEFINE}"'-Anweisung implementiert.
\end{note}

\subsubsection{Compiler-Ausgaben im Quelltext}

Innerhalb von Optionskommentaren im Quelltext d"urfen Zeichenketten
in einfachen oder doppelten Anf"uhrungszeichen vorkommen.
Sie werden vom Compiler auf dem Bildschirm ausgegeben, wenn sie nicht
innerhalb eines deaktivierten {\tt IF}-Zweiges
(siehe \ref{refCondComp}) stehen.

\begin{example}\begin{alltt}
  (*$ IF m68020 \dq{}ich kompiliere f"ur 68020!\verb|\|n\dq  *)
  ...
  (*$ ELSE \dq{}ich kompiliere nicht f"ur 68020!\verb|\|n\dq  *)
  ...
  (*$ ENDIF *)
\end{alltt}\end{example}


\subsection{Bedeutung der Optionen}

\newcommand{\compopt}[5]{\par\bigskip\noindent
\begin{tabular}{l|l|l|l}
\multicolumn{4}{l}{\bf #1} \\ \hline
#2 & #3 & #4 & #5 \\ \hline
\end{tabular}\nopagebreak\par\medskip\noindent}
%\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}c|c|c|c}\hline
%\multicolumn{4}{c}{#1} \\ \hline
%#2 & #3 & #4 & #5 \\ \hline
%\end{tabular*}\par\medskip\noindent}

Jede Option wird im folgenden in der Form
\compopt{Bedeutung}{Name}{interaktiv}{Typ}{Vorgabe}
dargestellt.
Hierbei bezeichnet
\begin{description}
\item[Name] den Namen der Option, mit dem sie im Quelltext ansprechbar
ist.
\item[interaktiv] ist der Buchstabe, der die Option von der Kommandozeile
(oder interaktiv) beeinflusst. Nicht alle Optionen sind von der
Kommandozeile beeinflussbar. F"ur sie erscheint die
Zeichenkette "`n.a."' (nicht anwendbar).
\item[Typ] bezeichnet den Typ und "Anderungsbereich der Option,
  d.h.\ ob sie stapelbar oder bereichsbezogen ist.
\item[Vorgabe] gibt den Vorgabewert (Default) der Option an:
\begin{itemize}
\item  "`TRUE"' = "`{\tt +}"' = eingeschaltet,
\item  "`FALSE"' = "`{\tt -}"' = ausgeschaltet.
\end{itemize}
\end{description}

\noindent
Es folgt nun eine genaue Beschreibung der Optionen im einzelnen:

\label{refStackChk}
\compopt{Stapelkontrolle}{StackChk}{s}{stapelbar}{TRUE}

Das Betriebssystem kontrolliert nicht, ob ein Prozess den ihm zugewiesenen
{\bf Stapelbereich} "uberschreitet. Ist dies der Fall, stellt sich meist
ein unerkl"arlicher Laufzeitfehler ein, dessen Ursache kaum feststellbar ist.
Der Compiler generiert Code zur "Uberpr"ufung des Stackbereichs. Diese
"Uberpr"ufung muss zu Beginn jeder Prozedur, sowie manchmal auch innerhalb
der Prozedur durchgef"uhrt werden. Dies vergr"ossert den Code und verlangsamt
das Programm. Werden keine Prozeduren
rekursiv aufgerufen, und ist sonst ein Stack"uberlauf unwahrscheinlich,
kann die Option ausgeschaltet werden.

Die Option wird zu Beginn jeder Prozedur eingefroren und am Ende wieder
freigegeben. Der "Anderbarkeitsbereich ist identisch mit dem der
bereichsbezogenen Optionen.

\compopt{Bereichskontrolle}{RangeChk}{r}{stapelbar}{TRUE}

Wird auf einen {\bf Unterbereich} ("'subrange"' wie \verb|[0..31]| oder
ein Feld wie \verb|a[3]|) zugegriffen, generiert der Compiler Code,
um die Einhaltung der Bereichsgrenzen zu "uberpr"ufen.
Unter- oder "Uberschreiten
eines solchen Bereichs bricht das Programm mit einem Laufzeitfehler ab.
Ist das
Programm vorsichtig ausgetestet (und nur dann), kann die Kontrolle
mit \verb|(*$ RangeChk:=FALSE *)| ausgeschaltet werden, um etwas
Geschwindigkeit zu gewinnen.

\begin{example}
\begin{verbatim}
  VAR i: INTEGER;
      zwerg: ARRAY[1..7] OF INTEGER;
  BEGIN
  FOR i:=1 TO 7 DO
    (*$ RangeChk:=FALSE *)
    zwerg[i]:=0;
    (*$ POP RangeChk *)
  END;
\end{verbatim}
Die Bereichskontrolle wird hier unmittelbar vor der Zuweisung der
Feldvariablen abgeschaltet und anschliessend wieder auf den alten Wert
zur"uckgesetzt.
\end{example}

Aber auch w"ahrend der Compilation hat diese Option eine Wirkung. Der
Compiler kann konstante Werte bereits zu dieser Zeit auf die Einhaltung
von Bereichsgrenzen "uberpr"ufen.

\begin{example}
So f"uhrt beispielsweise der folgende Text normalerweise
zu zwei Fehlermeldungen des Compilers:
\begin{verbatim}
  VAR range: [-2..5];
      i:INTEGER;
  ...
  range:=7;
  i:=12345678H;
\end{verbatim}
Bei ausgeschalteter Option wird keine Fehlermeldung erfolgen und die
Variable {\tt range} zur Laufzeit auf 7, sowie die Variable {\tt i} auf
den Wert 5678H gesetzt.
\end{example}

\begin{warning}
Die Laufzeit"uberpr"ufung von Zuweisungen zweier Variablen gleichen Typs
w"urde den Code extrem vergr"ossern und wird vom Compiler deshalb nicht
generiert! Eine "Uberpr"ufung erfolgt nur bei impliziten oder expliziten
Konvertierungen.

\begin{example}
\begin{verbatim}
  TYPE Farbe = (rot, gelb, gruen);
  VAR a,b: Farbe;
  a:=b; (* hier KEIN Laufzeittest! *)
\end{verbatim}
\end{example}
\end{warning}

\compopt{"Uber-, Unterlaufskontrolle}{OverflowChk}{v}{stapelbar}{TRUE}

Die interne Zahlenrepr"asentation kennt keine zu grossen oder zu kleinen
Zahlen. Jede "Uber- oder Unterschreitung bei der Berechnung von
Ausdr"ucken l"asst sich jedoch durch das Testen eines speziellen
Prozessor-Registers (CCR, "'condition code register"') feststellen. Der
Compiler generiert "Uber"-pr"u\-fungs\-code, der im Fehlerfall zur Laufzeit das
Programm abbricht. Ist das Programm vorsichtig ausgetestet, kann diese
Kontrolle durch 
\begin{quote} \verb|(*$ OverflowChk:=FALSE *)| \end{quote}
ausgeschaltet werden.

\compopt{Zeigerkontrolle}{NilChk}{n}{stapelbar}{TRUE}

Die Verwendung nicht-initialisierter Zeiger kann bei ihrer Dereferenzierung
zu unvorhersehbaren Ergebnissen und Programm-Abst"urzen f"uhren.
Der Compiler erzeugt Code, der zur Laufzeit testet, ob ein Zeiger
auf die Adresse 0 ({\tt NIL}) verweist. Dadurch kann zur Laufzeit das Programm
abgebrochen werden. Ist das Programm vorsichtig ausgetestet, kann diese
"Uberpr"ufung durch 
\begin{quote} \verb|(*$ NilChk:=FALSE *)| \end{quote}
ausgeschaltet werden.

\begin{warning}
Globale Variablen sind beim Programmstart immer mit 0 initialisiert,
lokale Variablen liegen jedoch auf dem Stack und enthalten ohne
spezielle Initialisierung zu
Beginn der Prozedur unsinnige, aber im allgemeinen von 0 verschiedene Werte.
Deshalb wird im Normalfall der Stack entsprechend initialisiert.
Wird jedoch dies mit der untenstehenden  Option {\tt EntryClear}
unterbunden, kann die
"Uberpr"ufung nicht greifen!
\end{warning}

\compopt{Nullinitialisierung}{EntryClear}{e}{stapelbar}{TRUE}

Da der Anfangswert einer lokalen Variablen nicht bestimmt
ist, werden diese explizit auf Null gesetzt.
Somit kann die Zeigerkontrolle richtig gut greifen. Soll diese
Operation nicht durchgef"uhrt werden, muss die Option
mit
\begin{quote}\verb|(*$ EntryClear:=FALSE *)| \end{quote}
ausgeschaltet werden.

\begin{warning}
Dies gilt jedoch {\em nicht\/} f"ur Register-Variablen und auch nicht,
wenn die Anzahl der lokalen Variablen 32kByte "ubersteigt!
\end{warning}

\compopt{Fall"uberpr"ufung}{CaseChk}{c}{stapelbar}{TRUE}

Wenn innerhalb einer {\tt CASE}-Anweisung der aktuelle Wert ausserhalb aller
angegebenen Teilbereiche liegt und {\em kein\/} {\tt ELSE}-Teil angegeben wurde,
wird das Programm mit einem Laufzeitfehler abgebrochen.
F"ur diese "Uber"-pr"u\-fung wird dazu vom Compiler Code generiert,
der durch die Option
\begin{quote}\verb|(*$ CaseChk:=FALSE *)| \end{quote}
vermieden wird. Die Wirkung
ist identisch mit der Angabe eines leeren {\tt ELSE}-Teiles.

\compopt{Funktionsr"uckgabe}{ReturnChk}{f}{stapelbar}{TRUE}

Am Ende jeder Funktionsprozedur generiert der Compiler Code, der im Falle
einer fehlenden {\tt RETURN}-Anweisung ausgef"uhrt wird und das Programm mit
einem Laufzeitfehler abbricht. Ist bei einer Funktionsprozedur die
ordnungsgem"asse Beendigung garantiert (und nur dann), kann die Generierung
des "Uberpr"ufungscodes mit 
\begin{quote} \verb|(*$ ReturnChk:=FALSE *)| \end{quote}
abgeschaltet werden.

\begin{note}
Da der Sprungoptimierer (siehe Seite \pageref{refOpti}) auch unbenutzten Code
entfernt, wird der "Uberpr"ufungscode bei Nichtbedarf wegoptimiert. Ist
also eine Funktionsprozedur "`sauber"', d.h.\ f"uhrt sie korrekte
{\tt RETURN}-Anweisungen aus und l"auft nicht einfach bis zum Ende durch, so ist
der "Uberpr"ufungscode unbenutzt (tot). Wenn eine
zweimalige Compilation --- einmal mit "`{\tt -df}"', einmal mit
"`{\tt -d}"' ---
in beiden F"allen die gleiche Codegr"osse erzeugt,
ist alles in Ordnung.
Andernfalls sind irgendwo in dem Modul noch "`unsaubere"'
Funktionsprozeduren!
Die Gr"osse des Codes wird am Schluss vom Compiler
angegeben.
 
\begin{example}
\begin{verbatim}
  MODULE FTest;
  PROCEDURE ret(i:INTEGER):INTEGER;
  BEGIN
    IF i=1 THEN
      RETURN 5
    END;
  END ret;
  END FTest.
\end{verbatim}
Nach der Kompilierung mit "`{\tt -d}"' meldet der Compiler
"`{\tt CODE:44}"', nach
nochmaliger Kompilierung mit "`{\tt -df}"' sagt er "`{\tt CODE:36}"'.
Wir sehen
also, dass der "Uberpr"ufungscode im ersten Fall nicht wegoptimiert werden
konnte, weil er f"ur den Fall {\tt i\#1} ben"otigt wird.
\end{example}
\end{note}

\compopt{Ein-/Ausgangs-Code}{EntryExitCode}{n.a.}{bereichsbezogen}{TRUE}

Jede Prozedur f"uhrt zu Beginn einen speziellen Code aus, der eine
Stapel"uberpr"ufung vornimmt, Platz f"ur die lokalen Variablen auf dem Stapel
alloziert, den {\bf dynamischen Link} erstellt, die innerhalb der Prozedur
benutzten Register auf dem Stack ablegt, und bei Bedarf die offenen
Feldparameter auf den Stack kopiert. Am Ende der Prozedur werden (bei
Funktionsprozeduren) der Code zur R"uckgabekontrolle generiert, die
zu Beginn geretteten Register vom Stapel geholt, die lokalen Variablen
und die Parameter abgebaut und eine R"uckkehranweisung ausgef"uhrt.

Diese beiden Codeteile werden nach 
\begin{quote} \verb|(*$ EntryExitCode:=FALSE *)| \end{quote}
nicht erzeugt. Dies wird vor allem bei reinen Assembler-Prozeduren, bei
denen der Programmierer f"ur alle oben genannten Aktionen selbst
verantwortlich ist, oder bei Prozeduren, die lediglich als
"`Verpackung"' f"ur Daten dienen, ben"otigt.

\begin{example}
\begin{verbatim}
PROCEDURE Ret0():LONGINT;
(*$ EntryExitCode:=FALSE *)
BEGIN
  ASSEMBLE(
     MOVEQ #0,D0
     RTS
  END);
END Ret0;

PROCEDURE Daten;
(*$ EntryExitCode:=FALSE *)
BEGIN
  ASSEMBLE(
    DC.W 1,2,3
    DC.B 'Moin, Moin!',0 EVEN
  END);
END Daten;
\end{verbatim}
\end{example}

\compopt{Offene Felder}{CopyDyn}{n.a.}{bereichsbezogen}{TRUE}

Eine Prozedur, die offene Feldparameter als Werteparameter besitzt,
muss diese zu Beginn auf den Stack kopieren, damit die "ubergebene
Variable oder Konstante nicht ver"andert werden kann (siehe auch
\ref{refOpenArrays}, Seite \pageref{refOpenArrays}). F"ur die
Herstellung der Kopie muss Code erzeugt werden. Falls der Parameter
innerhalb der Prozedur nicht ver"andert wird, kann das
Kopieren mit der Option 
\begin{quote} \verb|(*$ CopyDyn:=FALSE *)| \end{quote}
 unterbunden
werden, was Code und Laufzeit spart. Danach wird der Parameter wie
ein VAR-Parameter behandelt, beh"alt aber den Vorteil, dass auch
Konstanten "ubergeben werden k"onnen.

\begin{example}
\begin{verbatim}
(*$ CopyDyn:=FALSE *)
PROCEDURE Show(s:ARRAY OF CHAR);
BEGIN
  Write('"'); WriteString(s); Write('"');
END Show;
\end{verbatim}
\end{example}

\begin{warning}
Besonders, wenn mehrere Parameter "ubergeben werden, sollte man diese
Option mit "ausserster Vorsicht einsetzen, da der Benutzer der
Prozedur eventuell die {\em selbe\/} Variable einmal als
Werte- und einmal als VAR-Parameter "ubergeben k"onnte! Wenn dann der
VAR-Parameter ver"andert wird, wird gleichzeitig unbemerkt auch der
Wert-Parameter ver"andert.

\begin{example}
Das Ausschalten der Option w"urde im folgenden Beispiel zu einem falschen
Ergebnis f"uhren:
\begin{alltt}
PROCEDURE Swap(VAR dest:ARRAY OF CHAR;
               source:ARRAY OF CHAR);
BEGIN
  dest[0]:=source[1]; (* {\rm Hier wird source[0] unabsichtlich} *)
  dest[1]:=source[0]; (* {\rm "uberschrieben, falls source und} *)
  dest[2]:=0C;        (* {\rm dest die gleiche Variable enthalten} *)
END Swap;
...
  Swap(name,name);
...
\end{alltt}
\end{example}
\end{warning}


\compopt{Parameter-Abbau}{ParDealloc}{n.a.}{bereichsbezogen}{TRUE}

In \mtwo{} dealloziert jede Prozedur ihre Parameter selbst wieder,
da sie aus der Vereinbarung genau weiss, mit wievielen Parametern
sie aufgerufen wurde. In der Sprache C werden die Parameter vom Aufrufer
dealloziert, da nur dieser weiss, wieviele Parameter er "ubergeben hat. Einige
Betriebssystem-Prozeduren ben"otigen eine Prozedur als Parameter. Diese
d"urfen ihre Parameter dann allerdings nicht selbst abbauen, da dies ja
die aufrufende Prozedur des Betriebssystems tut. Der Parameter-Abbau kann
mit 
\begin{quote} \verb|(*$ ParDealloc:=FALSE*)| \end{quote}
unterbunden werden.

\begin{example}
Ein Beispiel aus der Graphik-Bibliothek {\tt graphics.library}.
Man beachte auch die umgekehrte Anordnung
der Parameter; C legt die Parameter in umgekehrter Reihenfolge als
\mtwo{} auf dem Stack ab (siehe \ref{refParaC}, Seite \pageref{refParaC},
Einbindung von C)! Die {\tt CAST}-Anweisung ist notwendig, weil
{\tt SetCollision}
als Parameter eine {\tt PROC} erwartet --- was dem allgemeinsten
Fall einer Prozedur entspricht ---, {\tt BorderPatrol} jedoch Parameter hat.
\begin{verbatim}
  PROCEDURE BorderPatrol(mask:LONGSET; spr:ExtSpritePtr);
  (*$ ParDealloc:=FALSE *)
  BEGIN
    ...
  END BorderPatrol;
  ...
  SetCollision(0,CAST(PROC,ADR(BorderPatrol)),GInfo);
  ...
\end{verbatim}
\end{example}


\compopt{Sichere und lade A4}{LoadA4}{n.a.}{bereichsbezogen}{FALSE}

Normalerweise wird das Register A4 von unserem
\mtwoamiga-Lauf\-zeit\-sy\-stem zu Beginn des
Programmes einmal mit der Basis der globalen \near-Variablen initialisiert
und w"ahrend des Programmlaufs nicht ver"andert.
Falls jedoch \mtwo-Prozeduren
vom Betriebssystem aufgerufen werden,
z.B. Interrupt-Handler, ist A4 zu Beginn der Prozedur
"`zerst"ort"' und muss neu "`beschafft"' werden. N"aheres steht in
\ref{refA4}, Seite \pageref{refA4}. Dort befindet sich auch ein ausf"uhrliches
Beispiel f"ur den Nutzen dieser Option. Die Angabe
\begin{quote} \verb|(*$ LoadA4:=TRUE *)| \end{quote}
gilt f"ur die n"achste Prozedur und bewirkt, dass Register A4 mit den anderen
Registern auf den Stack gerettet und mit der Basis der \near-Variablen
("`{\tt \_LinkerDB}"') geladen wird. Am Ende der Prozedur wird A4
wiederhergestellt.
Damit ist ein Programm nicht mehr
{\bf resident\-f"ahig}, da jeder Aufruf eines residentf"ahigen
Programms seine {\em eigenen\/} globalen Daten bekommt. Sie in
diesem Fall die folgende Option!

\compopt{Sichere A4}{SaveA4}{n.a.}{bereichsbezogen}{FALSE}

Diese Option ist fast identisch mit LoadA4.  Die Angabe
\begin{quote} \verb|(*$ SaveA4:=TRUE *)| \end{quote}
gilt f"ur die n"achste Prozedur und bewirkt, dass das Register A4
mit den anderen
Registern auf den Stack gerettet und am Prozedurende wiederhergestellt wird.
Hier wird also -- im Gegensatz zu LoadA4 --- das Register nicht explizit
mit einem Wert geladen, sondern nur gerettet. Es muss nun innerhalb der
Prozedur vom Programmierer "`per Hand"' gesetzt werden. Dadurch kann
die Residentf"ahigkeit eines Programmes erhalten werden. Auch hier
findet sich ein Beispiel im Abschnitt \ref{refA4}.

\compopt{Implementation}{Implementation}{n.a.}{pro Modul}{TRUE}

Zu jeder Symboldatei erwartet der Linker auch eine Objektdatei.
Besteht jedoch die Definition nur aus Typen- und
Kon\-stanten-Ver\-ein\-barungen
oder der Deklaration absoluter oder externer Variablen
und ist kein Code beim Import dieses Moduls auszuf"uhren --- vom Compiler
nur beim Imple"-men\-ta\-tions-Modul feststellbar ---, er"ubrigt sich eine
Objektdatei. In diesem Fall ist {\em vor dem ersten Import oder der
ersten Deklaration\/} die Compiler-Anweisung
\begin{quote} \verb|(*$ Implementation:=FALSE *)| \end{quote}
zu schreiben. Dies spart also des Schreiben eines "`leeren"'
Im\-ple\-men\-ta\-tions\-Moduls und die Ausf"uhrung unn"utzen Codes. Ein 
wenig Code muss sonst auch bei leeren Moduln erzeugt und durchlaufen werden.

\compopt{Bezeichnerkontrolle}{NameChk}{n.a.}{pro Modul}{TRUE}

\label{nameChk}
In einer Symboldatei werden alle Bezeichner der Prozedurparameter
abgelegt und deren "Ubereinstimmung in der Implementation "uberpr"uft.
Stimmen die Namen nicht "uberein, erfolgt eine Fehlermeldung.
Sollen die Bezeichner {\em nicht\/} vermerkt werden, kann in einem
Definitionsmodul das Ablegen der Bezeichner mit
\begin{quote} \verb|(*$ NameChk:=FALSE *)| \end{quote}
unterbunden werden. Der Nutzen liegt in kleineren und schneller
einzulesenden Symboldateien. Sollen nur die abgelegten Bezeichner nicht
"uberpr"uft werden, kann die Option zu Beginn des Implementationsmoduls
angegeben werden.

\compopt{Langwortgrenzen}{LongAlign}{l}{stapelbar}{TRUE}

Normalerweise werden globale Variablen, die mehr als ein
Byte belegen, auf Langwortgrenzen abgelegt. Dies ist manchmal
zwingend notwendig (z.B.\ {\tt DosD.FileInfoBlock}), l"asst aber auch
die Programme auf Prozessoren mit 32-Bit Datenbus ---
68020 und h"oher --- schneller laufen. Falls dies
nicht n"otig ist, kann durch die Angabe
\begin{quote} \verb|(*$ LongAlign:=FALSE *)| \end{quote}
eine dichteres Aufeinanderfolgen der Variablen erreicht werden. Sie
liegen dann auf Wortgrenzen. N"aheres ist im Abschnitt \ref{refAlignLong},
Seite \pageref{refAlignLong} zu finden.

\compopt{Zeiger vergessen}{Volatile}{h}{stapelbar}{TRUE}

Falls diese Option durch
\begin{quote} \verb|(*$ Volatile:=FALSE *)| \end{quote}
auf {\tt FALSE} gesetzt wird, versucht der Compiler, m"oglichst viele Zeiger
in Adressregistern zu halten und wiederzubenutzen, was enorm Code sparen
kann. N"aheres kann man in Abschnitt \ref{refVolatile},
Seite \pageref{refVolatile}
nachlesen.

\compopt{StackParameter}{StackParms}{z}{stapelbar}{TRUE}

Normalerweise m"ussen Parameter, welche die Register D0 oder D1 belegen,
bis zum endg"ultigen Prozeduraufruf zun"achst auf dem Stack zwischengelagert
werden, weil sie sonst durch andere Operationen zerst"ort werden k"onnten.
Durch
\begin{quote} \verb|(*$ StackParms:=FALSE *)| \end{quote}
wird erreicht, dass sie gleich, ohne Umweg "uber den Stack, in diesen
Registern abgelegt werden, was Code und Laufzeit spart. Hierbei k"onnen
jedoch Probleme auftreten; lesen Sie bitte Abschnitt \ref{refZ},
Seite \pageref{refZ}!

\compopt{Zeichenketten-Konstanten}{CStrings}{n.a.}{stapelbar}{TRUE}

Da die Sonderbehandlung des Zeichens "`\verb|\|"'
in Zei\-chen\-ketten-Kon\-stan\-ten
(siehe \ref{refCStrings}, Seite \pageref{refCStrings}) zu Inkompatibilit"aten
f"uhren kann, kann durch
\begin{quote} \verb|(*$ CStrings:=FALSE *)| \end{quote}
auf die normale Bedeutung dieses Zeichens umgeschaltet werden.

\compopt{Entwickler-Option}{Joker}{j}{stapelbar}{TRUE}

Diese Option ist den Entwicklern des \mtwoamiga-Systems zu Testzwe"cken
vorbehalten. Sie kann in jeder neuen Revision des Compilers eine andere
Bedeutung haben und sollte deshalb vom Anwender keinesfalls eingesetzt
werden!

\compopt{\far-Modell}{LargeVars}{y}{pro Modul}{TRUE}

Um die Anzahl und Gr"osse der globalen Variablen eines Moduls
nicht einzuschr"anken, wird jedes Modul standardm"assig im
\far-Modell kompiliert. Durch die Angabe
\begin{quote} \verb|(*$ LargeVars:=FALSE *)| \end{quote}
wird erreicht, dass es im \near-Modell kompiliert wird, also
alle globalen Variablen dieses Moduls \near{} sind, was die Codegr"osse
verringert, das Programm beschleunigt und vor allem Bedingung
f"ur residentf"ahige Programme ist. 
Was hierbei zu beachten ist, wird in Abschnitt \ref{refFar},
 Seite \pageref{refFar} n"aher erkl"art.
\begin{note}
Es wird empfohlen, alle Moduln mit der Option "`{\tt -y}"' zu
kompilieren. Am besten nehmen Sie diese Option in "`{\tt ENV:m2c}"'
(z.B. durch "`{\tt SetEnv m2c -y}"') mit auf.
\end{note}

\begin{warning}
Werden in einem Definitionsmodul globale Variablen deklariert, so
muss es mit der gleichen Option wie das Implementationsmodul kompiliert
werden, andernfalls erfolgt eine Fehlermeldung. Dies muss auch
befolgt werden, wenn keine Variablen in der Implementation 
deklariert wurden, da sich eine versteckte, f"ur den Benutzer nicht
zugreifbare Variable darin befindet!
\end{warning}

\compopt{Daten in Chip}{ChipDATA}{n.a.}{pro Modul}{FALSE}

Mit \mtwoamiga\ ist es m"oglich, globale Variablen
mit einem vorinitialisierten Wert zu versehen:
\begin{quote}\tt
  VAR
    i:=INTEGER{2};
\end{quote}
Diese Option entspricht in der Wirkungsweise der Option {\tt ChipCODE}.
Mit der Option {\tt ChipDATA} werden die so {\em vorinititialisierten
globalen\/}
Variablen (\ref{initVar}) im Chip-Memory abgelegt.

Daten m"ussen dann im Chip-Memory liegen,
wenn die Custom Chips des Amigas darauf zugreifen m"ussen.

\begin{warning}
Diese Option "uberlagert {\em stillschweigend\/} die Option {\tt LargeVars}!
Wenn Sie obige Option angeben, wird automatisch auf das \far-Modell
umgeschaltet, woraufhin das Programm nicht mehr residentf"ahig sein
kann. Wenn Sie unbedingt beides (Residentf"ahigkeit und CHIP-Daten)
ben"otigen, nutzen Sie f"ur {\em unver"anderliche\/} Daten entweder
externe Variablen oder die untenstehende Option {\tt ChipCODE}. F"ur
{\em ver"anderliche\/} Daten im Chip-Memory alloziert man den Speicher
besser zur Laufzeit!
\end{warning}

\compopt{Daten in Chip}{ChipBSS}{n.a.}{pro Modul}{FALSE}

Normalerweise wird f"ur die {\em nicht\/} vorinitialisierten
globalen Variablen eines Moduls
kein bestimmter Speichertyp verlangt, das Betriebssystem vergibt
den best"-m"og"|lichen.
Durch die Anweisung
\begin{quote} \verb|(*$ ChipBSS:=TRUE *)| \end{quote}
werden die globalen Daten des gesamten Moduls im Chip-Memory angelegt.

Der Einsatz dieser Option unterliegt den gleichen Einschr"ankungen
wie die Option {\tt ChipDATA}.

\compopt{Code in Chip}{ChipCODE}{n.a.}{pro Modul}{FALSE}

Hier gilt das gleiche wie unter {\tt ChipDATA} und {\tt ChipBSS}
gesagte. Durch die Anweisung
\begin{quote} \verb|(*$ ChipCODE:=TRUE *)| \end{quote}
wird der gesamte Code- und Konstanten-Bereich des Moduls im
Chip-Memory abgelegt.

\compopt{Zielprozessor}{m68000\ldots m68881}{0\ldots8}{pro Modul}{0}

Diese Optionen sind ausschliesslich von der Kommandozeile
durch die Ziffern {\tt 0}, {\tt 1}, {\tt 2}, {\tt 3},
{\tt 4} und {\tt 8} zu setzen. Sie dienen dazu, den {\bf Zielprozessor}
f"ur den erzeugten Code festzulegen 
 und so den optimalen Code zu erzeugen.
Der Zielprozessor muss dabei nicht unbedingt identisch mit dem
Prozessor des eigenen Amigas sein.

Standardeinstellung ist "`{\tt 0}"', d.h.\ der Compiler generiert Code, der
auf allen Prozessoren der MC68000er-Familie lauf"|f"ahig ist.

\begin{warning}
Die jeweils letzte Ziffer auf der Kommandozeile hat das "`letzte Wort"',
"`\hbox{\tt -38}"' ist also das gleiche wie "`\hbox{\tt -8}"'! Durch jede
Ziffer werden immer alle Optionen gesetzt. Die Angabe "`{\tt -18}"' ist also
unsinnig. Eine FPU~MC68881 impliziert f"ur den Compiler immer auch
mindestens eine MC68020-CPU.
Wenn Sie in Ihrem System einen 68010 mit 68881
haben --- was sehr unwahrscheinlich ist ---
kann der Compiler f"ur Sie nur 68010-Code
generieren.
\end{warning}

Bei der bedingten Kompilierung sind die in der Tabelle angegebenen
Namen in {\tt IF}-Abfragen erlaubt. Dabei ist zu beachten, dass all diese
Optionen in gegenseitiger Abh"angigkeit stehen, wie in Tabelle
\ref{compproc} zu sehen und unter \ref{refProzessoren},
Seite \pageref{refProzessoren} beschrieben ist.

\subsubsection{Optionen der Kommandozeile}

Nun folgen die Optionen, die nur von der Kommandozeile beeinflussbar
sind und bei der bedingten Compilation nicht benutzt werden k"onnen,
weil kein Name f"ur sie definiert ist. Wir stellen sie in folgender
Form dar:
\begin{quote} Zweck, Buchstabe, Vorgabewert \end{quote}


\begin{description}

\item[Debug-Info, d, TRUE]
\label{refOpti}

\par\noindent

Wenn von der Kommandozeile oder in
"`{\tt ENV:m2c}"'\footnote{Was der Umgebungsvariablen {\tt m2c}
entspricht} die
Option "`{\tt -d}"' angegeben wird, bedeutet dies:
"`kein Debugger"'. F"ur den Compiler heisst das:
\begin{enumerate}
\item Es wird keine "`{\tt .ref}"'-Datei, also keine Referenzdatei f"ur
den Debugger erzeugt und
\item der Code wird
so weit wie m"oglich optimiert. Hierbei werden unn"otige Dinge gel"oscht,
die sonst unter Umst"anden als
{\tt NOP}-Anweisungen\footnote{"'No Operation"'-Anweisung,
eine Anweisung, die keinerlei Funktion ausf"uhrt}
im Code erscheinen, Spr"unge wenn immer
m"og"-lich umgeleitet, gel"oscht oder verk"urzt.
\end{enumerate}

Diese Optimierung wird jeweils einzeln f"ur jede globale Prozedur, jedes zum
Hauptmodul lokale Modul und f"ur das Hauptmodul ausgef"uhrt.
Der Compiler gibt zu Beginn jeder Optimierung ein "`{\tt o}"'
auf dem Bildschirm
aus. Bei grossen Prozeduren (ab etwa 6\,kByte) wird dadurch eine
geringf"ugige Verz"ogerung bemerkbar, ansonsten geht es sehr schnell.
Am Schluss meldet der Compiler, wieviel Code er durch die Optimierung
eingespart hat.

\item[Referenz-Datei, @, n.a.]

\par\noindent

Die Option "`{\tt @}"' bewirkt bei der Einstellung
"`{\tt +@}"':
\begin{itemize}
\item Es wird eine "`{\tt .ref}"'-Datei
erzeugt und
\item der Code wird
analog zur obigen Option "`{\tt -d}"' optimiert.
\end{itemize}

Die so erzeugte Referenzdatei ist allerdings nur vom Profiler
und vom Library-Linker zu benutzen. F"ur den Debugger ist
diese Referenz-Datei {\em unbrauchbar\/}!

Mit der Option "`{\tt -@}"' wird
\begin{itemize}
\item keine Referenz-Datei erstellt
\item der Code nicht optimiert
\end{itemize}

Diese Form macht dann Sinn, wenn eine schnelle Compilation 
ge"-w"unscht wird, da Aufwand f"ur Optimierung und Erstellen
zus"atzlicher Dateien wegfallen.

Im "Uberblick bewirken die zwei Optionen "`{\tt d}"' und "`{\tt @}"'
folgendes:

\begin{center}
\begin{tabular}{|l|c|c|}\hline
& Mit Referenz & Ohne Referenz \\\hline\hline
Ohne Optimierung & +d & -@ \\\hline
Mit Optimierung & +@ & -d \\\hline
\end{tabular}
\end{center}

\item[Ikonen-Erzeugung, i, CLI: FALSE, Workbench: TRUE]

\par\noindent

Ist diese Option eingeschaltet, erzeugt der Compiler f"ur die Symbol-,
Objekt- und Referenz-Dateien Workbench-Ikonen. Der Standardwert
wird beim Start des Compilers vom CLI auf {\tt FALSE}, beim Start von der
Workbench auf {\tt TRUE} gesetzt. Wenn Sie auch beim CLI-Start Ikonen
w"unschen, geben Sie die Option "`{\tt +i}"' an. Ein L"oschen der Option
mit "`{\tt -i}"' bei der Workbench-Arbeit macht wenig Sinn, da Sie dann Ihre
erzeugten Dateien nur eingeschr"ankt sehen k"onnen\footnote{Ab
Workbench 2.0 sind auch ikonenlose Dateien darstellbar, haben allerdings
keine speziellen Ikonen. Bis zur Version 1.3 waren solche Dateien
von der Workbench aus nicht sichtbar}.

\item[Meldungen, q, TRUE]

\par\noindent

Nach der Eingabe "`{\tt -q}"' unterl"asst der Compiler s"amtliche
Meldungen "uber geladene Dateien oder Statistiken auf dem Bildschirm.
Im Fehlerfall geht der Compiler auch nicht in den interaktiven Modus.
So l"asst sich der Compiler auch in Batch-Dateien problemlos verwenden.

\item[Warnungen, w, TRUE]

\par\noindent

Warnungen sind Fehlermeldungen, die der Compiler erzeugt, wenn er w"ahrend
der Compilation auf Compiler-Optionen in der alten (bis M2Amiga
Version 3.3)
Syntax trifft (Ein Dollar-Zeichen, gefolgt von einem Buchstaben, gefolgt
von "`{\tt +}"', "`{\tt -}"' oder "`{\tt =}"' innerhalb eines Kommentars).

Als Hilfe f"ur die Umstellung "alterer Quelltexte oder bei der Portierung
von fremden Systemen ist dies sicherlich sehr n"utzlich, da so keine
"`alte"' Option "ubersehen werden kann.

Durch die Angabe "`{\tt -w}"' werden Warnungen unterdr"uckt.

\begin{note}
Warnungen k"onnen auch auftreten, wenn ein ASSEMBLE-Teil mit
Hexadezimalzahlen
auskommentiert wurde, da diese ebenfalls mit "`{\tt \$}"' beginnen!
\end{note}

\item[Profiler, p, FALSE]

\par\noindent

Nach der Angabe "`{\tt +p}"' erzeugt der Compiler Code, der zur Benutzung des
Profilers n"otig ist. Der Code ist dann aber nur {\em mit\/} dem Profiler
lauf"|f"ahig! Auf jeden Fall wird dann eine Referenzdatei erzeugt,
unabh"angig vom Setzen der Optionen "`{\tt d}"' und "`{\tt @}"'.
Eine Optimierung wird wie verlangt durchgef"uhrt.

\item[Verzeichniswechsel, g]

\par\noindent

Durch die Angabe "`{\tt -g\cmsltt Directory\/}"' setzt der Compiler das aktuelle
Verzeichnis auf "`{\cmsltt Directory\/}"'.
Die Option "`{\tt -g}"' allein wechselt
zur"uck in das Startverzeichnis.
Mit Hilfe dieser Option kann man sich
interaktiv --- sogar schon von der Kommandozeile aus --- durch mehrere Projekte
bewegen. Dies ist wichtig, damit die erzeugten Dateien im richtigen
Projekt abgelegt werden. Die Compilation von "`{\tt my:txt/Demo.mod}"'
findet zwar den Text, legt aber die Objekt-Datei im aktuellen Projekt ab.
Weitere Hinweise finden sich in \ref{refBedien} auf Seite \pageref{refBedien}.

\item[Benutzerdefinierte Optionen, o]

\par\noindent

Von der Kommandozeile sind benutzerdefinierte Optionen
mittels den Optionen \hbox{"`{\tt -o\cmsltt Name}"'} oder
 \hbox{"`{\tt+o\cmsltt Name}"'} zu setzen.
 Die Deklaration erfolgt im Programmtext mit der Anweisung
 "`{\tt DEFINE \cmsltt Name\/\tt:=\cmsltt Wert\/}"'.
 Die benutzerdefinierten Optionen haben keine direkte
 Wirkung auf den erzeugten Code, sondern dienen nur als Hilfsmittel f"ur
 die bedingte Compilation.

\item[Zieldatei, t]

\par\noindent

Im Zusammenhang mit der bedingten Compilation kann es sinnvoll
sein, eine eigene Objektdatei zu erzeugen. Die Option
"`{\tt -t\cmsltt Zieldatei}"' --- {\cmsltt Zieldatei\/}
darf keinen Pfad enthalten --- legt lediglich den {\em Dateinamen\/}
fest, der vom Compiler je nach gew"ahlter CPU und dem
Vorhandensein eines {\tt obj}-Verzeichnisses vervollst"andigt
wird. Der in der Objektdatei abgelegte {\em Modulname\/}
wird hierdurch {\em nicht\/} ver"andert. Die so erzeugten Dateien
k"onnen beim Linkvorgang mit den Optionen "`{\tt -a}"' oder
"`{\tt -l\cmsltt Dateiname\/}"' angegeben
und an Stelle der vorgegebenen Dateien geladen werden.
\end{description}

Die folgenden Tabellen geben eine "Ubersicht aller
Optionen. Dabei bezeichnet "`Name"' die
im Quelltext von Compiler-Anweisungen benutzbaren
Optionen. Tabelle \ref{compoptglob} gibt die allgemein verwendbaren
Optionen an. In Tabelle \ref{compoptspec} sind die 
von der Kommandozeile beeinflussbaren und prozessorw"ahlenden
Optionen beschrieben. Namen in Klammern dienen lediglich
der Erkl"arung und sind im Quelltext {\em nicht\/} definiert.

Eine Sonderstellung nehmen schliesslich die Optionen
der Prozessoren ein. Sie sind nur von der Kommandozeile
beeinflussbar und werden nach der Systematik gem"ass
Tabelle \ref{compproc} gesetzt.


\begin{table}[hbt]
\begin{center}
\begin{tabular}{|l|c|l|l|} \hline
Name	&Kommando& Typ		& Vorgabe \\ \hline \hline
%\multicolunm{4}{|c|}{Kommandozeile und Quelltext:} \\ \hline
StackChk	& s	 & stapelbar pro Prozedur	& TRUE \\ \hline
RangeChk	& r	 & stapelbar	& TRUE \\ \hline
OverflowChk	& v	 & stapelbar	& TRUE \\ \hline
NilChk		& n	 & stapelbar	& TRUE \\ \hline
EntryClear	& e	 & stapelbar	& TRUE \\ \hline
CaseChk		& c	 & stapelbar	& TRUE \\ \hline
ReturnChk	& f	 & stapelbar	& TRUE \\ \hline
LongAlign	& l	 & stapelbar	& TRUE \\ \hline
Volatile	& h	 & stapelbar	& TRUE \\ \hline
LargeVars	& y      & pro Modul	& TRUE \\ \hline
StackParms	& z	 & stapelbar	& TRUE \\ \hline
Joker   	& j	 & stapelbar	& TRUE \\ \hline
{\sl benutzerdefinert} & o{\sl Name}  & stapelbar	& --- \\ \hline \hline

%\multicolunm{4}{|c|}{Nur Quelltext:} \\ \hline
EntryExitCode	& ---	 & bereichsbezogen	& TRUE \\ \hline
CopyDyn		& ---	 & bereichsbezogen	& TRUE \\ \hline
ParDealloc	& ---	 & bereichsbezogen	& TRUE \\ \hline
LoadA4		& ---	 & bereichsbezogen	& FALSE \\ \hline
SaveA4		& ---	 & bereichsbezogen	& FALSE \\ \hline \hline

Implementation	& ---	 & pro Def-Modul& TRUE \\ \hline
NameChk		& ---	 & pro Modul	& TRUE \\ \hline
ChipBSS		& ---	 & pro Modul	& FALSE \\ \hline
ChipDATA	& ---	 & pro Modul	& FALSE \\ \hline
ChipCODE	& ---	 & pro Modul	& FALSE \\ \hline
CStrings	& ---	 & stapelbar	& TRUE \\ \hline \hline
\end{tabular}
\caption{\label{compoptglob} allgemeine Compiler-Optionen}
\end{center}
\end{table}

\begin{table}[hbt]
\begin{center}
\begin{tabular}{|l|c|l|l|} \hline
%\multicolunm{4}{|c|}{Nur Kommandozeile:} \\ \hline
(Debug)		& d	 & pro Modul	& TRUE \\ \hline
(Ref)		& @	 & pro Modul	& --- \\ \hline
(Meldungen)	& q	 & pro Modul	& TRUE \\ \hline
(Ikonen)	& i	 & pro Modul	& TRUE \\ \hline
(Warnungen)	& w	 & pro Modul	& TRUE \\ \hline
(Profiler)	& p	 & pro Modul	& FALSE \\ \hline
(Verzeichnis)   & g{\sl Directory} & --- & --- \\ \hline
(Zieldatei)     & t{\sl TargetName} & pro Modul & {\sl Modulname} \\
\hline \hline

%\multicolunm{4}{|c|}{Von Kommandozeile ver"anderbar, im Quelltext lesbar} \\ \hline
MC68000    	& 0	 & pro Modul	& TRUE \\ \hline
MC68010		& 1	 & pro Modul	& FALSE \\ \hline
MC68020		& 2	 & pro Modul	& FALSE \\ \hline
MC68030		& 3	 & pro Modul	& FALSE \\ \hline
MC68040		& 4	 & pro Modul	& FALSE \\ \hline
MC68881		& 8	 & pro Modul	& FALSE \\ \hline
\end{tabular}
\caption{\label{compoptspec} Compiler-Optionen der Kommandozeile und
  f"ur Prozessorwahl}
\end{center}
\end{table}

\begin{table}[h]
\begin{center}
\begin{tabular}{|c||c|c|c|c|c|} \hline
Ziffer & MC68010 & MC68020 & MC68030 & MC68040 & MC68881 \\ \hline\hline
 0 & FALSE & FALSE & FALSE & FALSE & FALSE \\ \hline
 1 & TRUE & FALSE & FALSE & FALSE & FALSE \\ \hline
 2 & TRUE & TRUE & FALSE & FALSE & FALSE \\ \hline
 3 & TRUE & TRUE & TRUE & FALSE & FALSE \\ \hline
 4 & TRUE & TRUE & FALSE & TRUE & TRUE \\ \hline
 8 & TRUE & TRUE & TRUE & FALSE & TRUE \\ \hline
\end{tabular}
\caption{\label{compproc}Systematik der Prozessoroptionen}
\end{center}
\end{table}

