,,Level`` bedürfen einer weiteren Erklärung: Falls eine lokale Prozedur auf Variablen oder Parameter einer weiter aussen liegenden Zugriff benötigt, muss sie sich zunächst am ,,static link`` (siehe 5.5.3) ,,entlanghangeln``. Dazu wird Code erzeugt, der bei einem späteren Zugriff auf denselben Level unterbleiben kann, wenn der angelegte Zeiger noch in einem Adressregister vorhanden ist.
Durch die Option ,,Volatile:=FALSE`` (Kommandozeile: -h) versucht der Compiler Zeiger folgender Art in Adressregistern zu halten:
Die Wirkung lässt sich wohl am ehesten als ,,vollautomatisches WITH``
(ohne Schreiberleichterung) umschreiben. Dies spart sehr viel Code,
unter Umständen mehr als ein
echtes WITH. Ein echtes WITH kann natürlich mehr
(WITH x^.y^
oder WITH x^[y]
),
hat aber den Nachteil, dass ein Adressregister blockiert wird,
wohingegen bei diesem Verfahren der Register-Erhaltung bei
,,Registermangel`` einfach der Inhalt vergessen und bei Bedarf neu
geladen werden kann.
Der Compiler geht sehr vorsichtig vor, indem er nach einem Prozeduraufruf immer von dem ,,schlimmsten Fall`` ausgeht, dass alle Objekte, auf die die Prozedur Zugriff hat, zerstört sind (globale Prozeduren haben z.B. keinen Zugriff auf die lokalen Variablen und Werte-Parameter). Ebenfalls als zerstört gelten Zeiger selbstverständlich nach direkten Zuweisungen und nach der Benutzung als VAR-Parameter eines Prozedur-Aufrufs.
Dennoch kann die Strategie leicht zu Fall gebracht werden, indem irgendein Zeiger auf eine der oben genannten Variablen zeigt und deren Wert verändert. Damit hat dann die Variable im Speicher einen anderen Wert als das Register. Dies kann der Compiler nicht feststellen! Aus diesem Grunde wird diese Optimierung auch nur auf Wunsch vorgenommen.
Als Faustregel kann man sagen, dass Prozeduren und Moduln, die nicht mit Zeigern oder Listen arbeiten, immer mit der Option ,,Volatile:=FALSE`` kompiliert werden können. Der Vorteil liegt dabei im Merken der Adressen von VAR-Parametern.
Sobald Zeiger auf globale oder lokale Variablen zeigen, insbesondere bei Listenverarbeitung sollte die Option immer auf TRUE gesetzt sein! Wenn dennoch unbedingt Code eingespart werden soll, kann die (unschöne) Methode des Ausprobierens helfen. Im Compiler selbst musste nur eine einzige Prozedur mit ,,Volatile:=TRUE`` kompiliert werden.