|
11.3.4 Anforderungen an die Vorauswertung
Die Elaboration einer Deklaration oder eines Initialisierungsteils eines Pakets
(Vorauswertung) findet vor der Programmausführung statt. Oft kann bereits
der Übersetzer die mit der Elaboration einer Deklaration verbundene Arbeit
verrichten. Wenn alle Deklarationen in einem Paket vorauswertbar sind, dann
kann
z. B. der hierfür vorgesehene Speicher in der ausführbaren Datei initialisiert
oder der mit vorausgewerteten Konstanten initialisierte Speicher in EPROMS gebrannt
werden. Die Deklarationen und Rümpfe von Bibliothekseinheiten, die in den
Pragmas "Preelaborate" und "Pure" benannt sind, werden vor
jeder anderen Übersetzungseinheit ausgewertet. Das bedeutet nicht, daß
sie notwendigerweise vor dem Programmlauf ausgewertet werden, sondern nur, daß
sie ausgewertet werden könnten.
pragma Preelaborate ( Name_einer_Bibliothekseinheit );
pragma Pure ( Name_einer_Bibliothekseinheit ); |
Das Pragma "Preelaborate" besagt, daß eine Einheit vor der
Ausführung eines Programms ausgewertet werden kann, i. a. bedeutet das, daß
die Einheit statisch ist und keinen Programmcode enthält.
Das Pragma "Pure" zeigt an, daß die Einheit nicht nur vorauswertbar
ist, sondern i. a. nur Konstanten enthält.
Die meisten vordefinierten Bibliothekseinheiten enthalten die Pragmas "Preelaborate"
oder "Pure", so daß sie bei der Vorauswertung von anderen Übersetzungseinheiten
verwendet werden können.
Die Pragmas "Preelaborate" und "Pure" können nur auf eine Bibliothekseinheit
angewendet werden, wenn diese Einheit bestimmten Einschränkungen unterliegt.
Diese Einschränkungen stellen sicher, daß die Deklaration und der Rumpf
einer Bibliothekseinheit ausgewertet werden können, ohne bestimmte Aktionen
durchzuführen, die nur während der Programmausführung sinnvoll
sind. Eine Deklaration wird als vorauswertbar (preelaborable) bezeichnet, wenn
sie ausgewertet werden kann, ohne daß folgendes zu tun ist:
- Berechnung einer Variablen.
- Berechnung einer Konstanten, die kein statischer Ausdruck ist. Aufruf eines
Unterprogramms, das kein vordefinierter Operator oder ein Funktionswertattribut
ist (function-valued attribute), das in einem statischen Ausdruck erlaubt wäre.
- Erzeugen eines überwachten Typs (sogar als Komponente eines anderen Objektes),
weil dies den Aufruf der Prozedur "Initialize" des Typs erfordern würde.
Erzeugen eines Objektes eines privaten Typs oder eines Typs mit Komponenten, die
in einer privaten Erweiterung, die keinen expliziten Initialisierungswert hat,
vereinbart sind.
- Durchführung von Aktionen in Paketinitialisierungsanweisungen....von
Aktionen in Paketinitialisierungsanweisungen.n in Paketinitialisierungsanweisungen.
Wenn der Name einer Bibliothekseinheit in einem Pragma "Preelaborate" angegeben
ist, dann treffen folgende Einschränkungen auf die Deklaration, den Rumpf
und auf alle Untereinheiten des Rumpfes zu:
- Wenn diese Übersetzungseinheit eine Paketvereinbarung oder ein Paketrumpf
ist, müssen alle enthaltenen Deklarationen vorauswertbar sein.
- Wenn diese Übersetzungseinheit eine generische Ausprägung ist, dann
muß die generische Ausprägung selbst vorauswertbar sein (z. B. darf
keiner der generischen aktuellen Parameter eine Variable sein) und die Ergebnisinstanz
muß vorauswertbar sein (z. B. kann sie kein Paket sein, das eine Variable
zur Verfügung stellt, die durch den Aufruf einer vom Programmierer definierten
Funktion initialisiert wird.)
- Alle Einheiten von denen diese Übersetzungseinheit semantisch abhängt,
müssen entweder ein Pragma "Preelaborate" oder "Pure"
enthalten.
Die Einschränkungen, die mit dem Pragma "Pure" verbunden sind, schließen
alle mit dem Pragma "Preelaborate" verbundenen ein, hinzu kommen einige zusätzliche.
(D.h. das Pragma "Pure" kann als strengere Version des Pragmas "Preelaborate"
gesehen werden.) Damit eine Bibliothekseinheit in einem Pragma "Pure" benannt
werden darf, müssen die folgenden Einschränkungen für die Vereinbarung,
den Rumpf und die Untereinheiten der Bibliothekseinheit gelten:
- Wenn diese Übersetzungseinheit eine Paketvereinbarung oder ein Paketrumpf
ist, dann müssen alle enthaltenen Vereinbarungen vorauswertbar sein. Weiterhin
sind Variablenvereinbarungen (variable declarations) und Zugriffstypvereinbarungen
(access-type declarations) verboten, und eine geschachtelte Paketvereinbarung
oder ein Paketrumpf, die selbst eine verbotene Vereinbarung enthalten, sind verboten.
- Wenn diese Paketvereinbarung eine generische Ausprägung ist, dann muß
sie vorauswertbar sein. Weiterhin muß die als Ergebnis entstehende Ausprägung
vorauswertbar sein und darf keine verbotenen Vereinbarungen enthalten (Variablenvereinbarungen,
Zugriffstypvereinbarungen oder geschachtelte Paketvereinbarungen oder -rümpfe,
die verbotene Vereinbarungen enthalten).
- Alle Einheiten von denen die Übersetzungseinheit semantisch abhängt,
müssen auch ein Pragma "Pure" enthalten. (Ein Pragma "Preelaborate"
ist nicht ausreichend.)
Wenn ein Unterprogramm in einem Pragma "Pure" benannt wird, oder
es in einem Paket enthalten ist, das in einem Pragma "Pure" benannt
wird, dann kann das Unterprogramm auf keine Variable und keinen Zugriffstyp zugreifen,
die außerhalb seines Unterprogrammrumpfes vereinbart sind. (Die Einschränkung
auf semantische Abhängigkeit besagt, daß die with-Klausel der Einheit
nur andere Einheiten benennen kann, die auch in Pragmas "Pure" benannt
sind und so keine Variablen- oder Zugriffstypvereinbarungen enthalten.) Jedes
andere Unterprogramm, das von diesem Unterprogrammrumpf aufgerufen werden kann,
unterliegt den gleichen Einschränkungen. Es folgt, daß das Unterprogramm
nur als Auswirkungen haben kann, daß ein Wert zurückgegeben wird (wenn
es eine Funktion ist) oder die aktuellen Ein-/Ausgabe- oder Ausgabeparameter gesetzt
werden (wenn es eine Prozedur ist). Weiterhin sind diese Funktionsergebniswerte
und Ausgabeparameterwerte vollständig durch die Werte der Eingangsparameter
des Unterprogramms bestimmt.
Ein optimierender Übersetzer kann diese Tatsachen nutzen, um effizienteren
Code für Einheiten, die das Unterprogramm aufrufen, zu erzeugen . Wenn z.
B. "F" eine Funktion ist, auf die das Pragma "Pure" anwendbar
ist, dann kann der Ausdruck
0 < F(X) and F(X) < F(Y)
so übersetzt werden, daß der rechte Ausdruck nicht berechnet wird,
wenn F(X) einen negativen Wert zurückgibt, weil das Gesamtergebnis damit
schon feststeht. Wenn F(X) keinen negativen Wert zurückgibt, dann wird dieser
Wert bei der Berechnung des rechten Operanden von "and" wiederverwendet,
ohne den Aufruf F(X) ein zweites Mal auszuführen.
|