11. Anlage
 
zurück
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.


 
zurück
 Index   Ada Tour - Dokumentation  
© 2003 Förderverein Ada Deutschland e.V.