with Urknall;  -- Dieses Paket ist tabu für alle Zeiten!

package Universum is

  -- Nicht vererbbare Definitionen:

  PI: constant := Urknall.PI;

  Unzulaessiges_Argument: exception renames Urknall.Unzulaessiges_Argument;

  ----------------------------------------------------------------------
  -- Typen mit Mathematik:

  type    SI_Einheit        is new Urknall.Ur_Float;
  subtype Meter             is     SI_Einheit;
  subtype Sekunde           is     SI_Einheit;
  subtype Meter_pro_Sekunde is     SI_Einheit;
  subtype Radiant           is     SI_Einheit;
  subtype Dimensionslos     is     SI_Einheit;
  -- Andere SI-Einheiten

  type Grad is new Urknall.Ur_Float;

  function Grad_zu_Radiant (D: Grad   ) return Radiant;
  function Radiant_zu_Grad (R: Radiant) return Grad;

  ----------------------------------------------------------------------
  -- Typen ohne Mathematik:

  type Kilometer is new Urknall.Ur_Float_ohne_Mathematik;

  function Kilometer_zu_Meter (km: Kilometer) return Meter;
  function Meter_zu_Kilometer ( m: Meter    ) return Kilometer;

  type    Nautische_Einheit is new Urknall.Ur_Float_ohne_Mathematik;
  subtype Nautische_Meile   is     Nautische_Einheit;
  subtype Stunde            is     Nautische_Einheit;
  subtype Knoten            is     Nautische_Einheit;

  function Nautische_Meile_zu_Meter (NMi: Nautische_Meile) return Meter ;
  function Meter_zu_Nautische_Meile (m  : Meter          ) return Nautische_Meile;

  function Stunde_zu_Sekunde (h: Stunde ) return Sekunde;
  function Sekunde_zu_Stunde (s: Sekunde) return Stunde;

  function Knoten_zu_Meter_pro_Sekunde (kts: Knoten           ) return Meter_pro_Sekunde;
  function Meter_pro_Sekunde_zu_Knoten (mps: Meter_pro_Sekunde) return Knoten;

  -- Andere Nicht-SI-Einheiten und Umwandlungsfunktionen von und zu SI-Einheiten

  ----------------------------------------------------------------------
  -- Verstecken fehlerhafter Funktionen:

  function SinD (X: Radiant) return SI_Einheit renames Sin;   -- 1
  function Sin  (X: Grad   ) return Grad       renames SinD;  -- 2
  -- Restliche trigonometrische Funktionen und ihre Umkehrungen

  ----------------------------------------------------------------------
  -- Definition neuer Funktionen:

  function Sin  (X: Grad) return SI_Einheit;
  function SinD (X: Grad) return SI_Einheit renames Sin;
  -- Restliche trigonometrische Funktionen und ihre Umkehrungen

  ----------------------------------------------------------------------
  -- Sichtbarmachen des Typs mit allen seinen Operatoren, den die unären
  -- Operatoren "+" und "-" und die Funktion Masszahl der von Ur_Einheit
  -- abgeleiteten Typen ebenfalls benötigen:

  subtype Reell is Urknall.Ur_Float_ohne_Mathematik;

  function "<" (L, R: Reell) return Boolean renames Urknall."<";
  function "+" (L, R: Reell) return Reell   renames Urknall."+";
  function "/" (L, R: Reell) return Reell   renames Urknall."/";
  ...

end Universum;

Anmerkungen zum Code:

1 Diese Umbenennung verdeckt die fehlerhafte implizit deklarierte Funktion, die das Argument in Grad interpretiert, d.h. die verdeckte Funktion SinD liefert den Wert 1 für x = 90 rad, wohingegen die neue (richtige) Funktion diesen Wert für x = PI/2 rad liefert.

2 Dies verdeckt die fehlerhafte implizit deklarierte Funktion, die das Argument in Radiant interpretiert.

Das Paket ist genau zu testen, da einerseits sehr leicht Schreibfehler oder unterlassene Qualifizierung zu falschen Ergebnissen führen können, andererseits Compiler auf Grund der Überladung und der Wechselwirkung von impliziten und expliziten Vereinbarungen fehlerhaften Code erzeugen können. Im gegebenen Fall waren die Nichtverwendung von pragma Inline und eine passende Reihenfolge der Verdeckung falscher Funktionen und Neuvereinbarung weiterer Überladungen in der Paketspezifikation wesentlich, obwohl diese Reihenfolge eigentlich keinen Einfluß auf die Semantik ausüben darf.


Zurück zum Text.