Programmiersprache Pascal

Äquivalenz von Datentypen

In einer Reihe von Situationen ist es wichtig zu wissen, wie verschiedene Datentypen zueinander stehen:
  1. Können Werte mit verschiedenem Datentyp gemeinsam in einem Ausdruck stehen ?
  2. Kann in einer Ergibtanweisung der Ausdruck auf der rechten Seite einen anderen Datentyp besitzen als die Variable auf der linken Seite ?
  3. Kann bei der Übergabe von Parametern der Typ des aktuellen Parameters vom Typ des formalen Parameters abweichen ?
Im allgemeinen Fall müssen alle drei Fragen verneint werden. Es gibt jedoch - mitunter im Detail recht komplizierte - Regeln, welche über die Kompatibilität der einzelnen Datentypen zueinander entscheiden.
Generell läßt sich sagen, daß sich die Forderungen von Situation 1 zu Situation 2 zu Situation 3 jeweils verschärfen.

Typverträglichkeit innerhalb von Ausdrücken

Numerische Datentypen.

Operand1     Operand2      Resultat
-----------------------------------
INTEGER      INTEGER       INTEGER
INTEGER      REAL          REAL
REAL         REAL          REAL
Ist der Datentyp der Operanden unterschiedlich, so wird für den Datentyp des Resultats immer der umfassendere Typ gewählt. REAL ist in diesem Sinne umfassender als INTEGER.
Analog wird auch verfahren, wenn die Operanden einem Teilbereichstyp mit Basisdatentyp INTEGER angehören: Das Resultat besitzt den wertemäßig umfassenderen Datentyp.

Pascal++

Es ist zusätzlich der Datentyp COMPLEX verfügbar. COMPLEX ist umfassender als REAL.

Operand1     Operand2      Resultat
-----------------------------------
INTEGER      INTEGER       INTEGER
INTEGER      REAL          REAL
INTEGER      COMPLEX       COMPLEX
REAL         REAL          REAL
REAL         COMPLEX       COMPLEX
COMPLEX      COMPLEX       COMPLEX
Typverträglichkeit bei Ergibtanweisungen

Ergibtanweisungen werden im weiteren wie folgt beschrieben:

  linke_seite := rechte_seite;
linke_seite muß eine Variable sein, rechte_seite ist ein Ausdruck.

Numerische Datentypen

Standard Pascal

linke_seite     rechte_seite    zulässig
---------------------------------------------
INTEGER         INTEGER         ja
INTEGER         REAL            nein
REAL            REAL            ja
Beispiel:
  VAR i, j : INTEGER;
      r, s : REAL;
  
  i := 1; r := 1.0;
  s := r + i;                     { zulaessig }
  j := r + i;                     { nicht zulaessig }
  j := Round(r) + i;              { zulaessig }
Pascal++

linke_seite     rechte_seite    zulässig
---------------------------------------------
INTEGER         INTEGER         ja
INTEGER         REAL            nein
INTEGER         COMPLEX         nein
REAL            REAL            ja
REAL            COMPLEX         nein
COMPLEX         COMPLEX         ja
Beispiel:
  PROGRAM cmplex(OUTPUT);
  VAR c : COMPLEX;
  BEGIN
    c := Cmplx(1.1, 2.2);
    Writeln(Re(c), ' ', Im(c));        { liefert 1.1  2.2 }
    c := 1.1;
    Writeln(Re(c), ' ', Im(c));        { liefert 1.1  0.0 }
    c := 1;
    Writeln(Re(c), ' ', Im(c));        { liefert 1.0  0.0 }
    c := c + 1.1;
    Writeln(Re(c), ' ', Im(c));        { liefert 2.1  0.0 }
    c := c - 2;
    Writeln(Re(c), ' ', Im(c));        { liefert 0.1  0.0 }
  END.
Typverträglichkeit bei der Parameterübergabe

Numerische Datentypen

Pascal++

Das Verhalten ist analog wie bei der Ergibtanweisung.

Zwei Datentypen t1 und t2 sind kompatibel, wenn gilt:

Zugleich muß die Umkehrung gelten.

Äquivalenz von Datentypen

Es gibt verschiedene Ansätze für die Äquivalenz von Datentypen:

Beispiel:
  TYPE t1 = 1..100;
       t2 = 1..100;
  VAR a1 : t1;
      a2 : t2;
      b1 : t1;
      b2 : t1;
      c1, c2 : t1;
Die folgenden Zuweisungen sind zulässig
                  Struktur-       Namens-       Deklarations-
				äquivalenz
  -----------------------------------------------------------
  a2 := a1;          ja            nein             nein
  b2 := b1;          ja            ja               nein
  c2 := c1;          ja            ja               ja
Bei Strukturäquivalenz sind zwei Variablen zuweisungskompatibel, wenn sie Werte aus dem gleichen Wertebereich (domain) annehmen können.
Entscheidend bei der Strukturäquivalenz ist nicht der Typname, sondern die Typdefinition, durch die der Wertebereich bestimmt wird.
Typnamen erhalten somit keinen semantischen Gehalt, sondern sind einfach nur Abkürzungen.

Die Namensäquivalenz geht davon aus, daß zwei Variablen zuweisungskompatibel sind, wenn sie denselben (vordefinierten oder benutzerdefinierten) Typnamen haben. Der Typname erhält damit einen semantischen Gehalt.

Deklarationsäquivalenz liegt dann vor, wenn zwei Variablen in der gleichen Anweisung deklariert worden sind.

Beispiel:

  TYPE t1 = [1..10];
  TYPE t2 = [1..10];

  VAR a : t1;
      b, c : t1;
      d : t2;
Strukturäquivalenz
a, b, c und d sind zueinander zuweisungskompatibel
Namensäquivalenz
a, b und c sind zueinander zuweisungskompatibel, aber nicht d
Deklarationsäquivalenz
b und c sind zueinander zuweisungskompatibel, aber nicht a und d
Für manche Programmiersprachen wird in der Sprachdefinition festgelegt, welches Konzept der Prüfung auf Typkompatibilität zugrunde liegt, in anderen bleibt dies den jeweiligen Implementierungen überlassen. Dies hat zur Konsequenz, daß Probleme bei der Portierung von Programmen auftreten können.

Namensäquivalenz
Ada, Modula-2, Oberon
Strukturäquivalenz
C, C++, Modula-3, Pascal


P. Böhme, 15.09.1995