Zuweisungskompatibilität
# Zuweisungskompatibilität

Zuweisungskompatibilität liegt bei in Programmiersprachen formulierten Anweisungen vor, wenn Ausdrücke und Variablen aufgrund kompatibler Datentypen einander zugewiesen, miteinander verglichen oder miteinander verknüpft werden können.

Compiler oder Interpreter können bei typsicheren Programmiersprachen bereits im Quelltext prüfen, ob eine hinreichende Zuweisungskompatibilität vorliegt. Um eine Typverletzung zu beheben, muss durch den Compiler beziehungsweise Interpreter eine implizite oder durch den Programmierer eine explizite Typumwandlung durchgeführt werden. In beiden Fällen kann es leicht zu Programmfehlern kommen und daher ist in vielen modernen Programmiersprachen die implizite Typumwandlung nur in den Ausnahmen zulässig, wo sie die Quelltexte vereinfacht, aber keine Gefahr darstellt.

## Strenge Zuweisungskompatibilität

Zuweisungen sind uneingeschränkt zulässig, wenn eine strenge Zuweisungskompatibilität gegeben ist. Dazu müssen die Datentypen des zuzuweisenden Ausdrucks und der Variable exakt übereinstimmen.

Bei Verbunden müssen die Anzahl, die Reihenfolge und die Datentypen aller Komponenten des Verbunds übereinstimmen, was dadurch gewährleistet werden kann, dass alle beteiligten Variablen mit demselben Datentyp deklariert worden sind. Beispiel:

Bei Feldern ist die strenge Zuweisungskompatibilität nur gegeben, wenn der Basisdatentyp und die Länge identisch sind. Beispiel:

Ein Sonderfall sind offene Felder mit nicht deklarierter Länge: Bei formalen Parametern beziehungsweise dynamisch erst zur Laufzeit vollständig definierten Feldern reicht zur Erlangung der Zuweisungskompatibilität die Übereinstimmung des jeweiligen Basisdatentyps der Felder. Beispiel:

Bei Prozedurvariablen müssen die Anzahl, die Art, die Reihenfolge und die Datentypen aller Parameter und Rückgabewerte übereinstimmen, also abgesehen vom Prozedurnamen die Signaturen der beiden Prozeduren übereinstimmen.

Zwei Instanzen sind in diesem Sinne zuweisungskompatibel, wenn sie exakt derselben Klasse angehören. Beispiel:

### Logische Kompatibilität

Bei besonders strenger Betrachtungsweise sind sogar zwei identische Definitionen von Datentypen nicht zuweisungskompatibel, weil zwar die Daten eindeutig ineinander überführt werden können (technische Kompatibilität), aber zwei verschiedene Definitionen verwendet wurden (logische Kompatibilität). Folgendes Beispiel wäre demzufolge technisch korrekt, aber nicht logisch:

Um logische Programmfehler zu vermeiden, sind solche Zuweisungen mit impliziter Typumwandlung in einigen Programmiersprachen mit verhältnismäßig starker Typisierung, wie zum Beispiel Modula-2 oder Oberon, nicht zulässig.

## Zuweisungskompatibilität ohne Informationsverlust

In gewissen Fällen kann die Information, die in einem Datentyp abgelegt ist, eindeutig und ohne Informationsverlust in einen anderen Datentyp überführt werden.

Typische Beispiele sind ganzzahlige Datentypen mit unterschiedlicher Speichergröße. So kann ein Integer mit 16 Bit Speichergröße eindeutig in einer vorzeichenbehafteten Integer-Variablen mit 32 Bit Speichergröße abgelegt werden, ohne dass die ursprünglich nur mit 16 Bit definierte Zahl verändert wird. Umgekehrt ist dies jedoch nicht immer möglich, insbesondere unter der Beachtung von Vorzeichen und zu großen Zahlen.

Weitere Beispiele ergeben sich bei Zeichenketten oder anderen Feldern, deren feste Länge verschieden ist. Das kürzere Feld kann im längeren gespeichert werden, aber nicht umgekehrt.

Zwei Instanzen sind ohne Informationsverlust zuweisungskompatibel, wenn sie die zuzuweisende Klasse derselben Klasse angehört wie die zugewiesene Klasse.

### Beispiel ohne Zuweisungskompatibilität

Bei einer solchen Zuweisung kann bereits der Compiler verhindern, dass ausführbarer Maschinencode erzeugt wird, da nicht sichergestellt werden kann, dass große Zahlen, die in der Variable „zahl2“ gespeichert sind, immer auch ohne Informationsverlust in der Variable „zahl1“ abgelegt werden können.

Bei fehlender Überprüfung durch den Compiler werden zwangsläufig und unbemerkt Ziffern abgeschnitten, so dass bei nachfolgenden Berechnungen unter Umständen grobe Berechnungsfehler auftreten können, die teilweise schwierig zu analysieren sind.

## Zuweisungskompatibilität mit geringem Informationsverlust

Ein Sonderfall ist die Zuweisung von ganzen Zahlen an Variablen, die Gleitkommazahlen repräsentieren. Meist kann ohne die Gefahr von Programmfehlern toleriert werden, große ganze Zahlen implizit in Gleitkommazahlen umzuwandeln, da der Rechenfehler (wenn überhaupt vorhanden) hierbei sehr klein ist. Auch dies kann an einem Beispiel verdeutlicht werden:

Der Fehler durch das Abschneiden der letzten Nachkommastellen liegt hier also nur in einer Größenordnung von ${10}^{-14}$ und kann daher für praktisch alle Anwendungen vernachlässigt werden.

## Zuweisungskompatibilität mit definiertem Informationsverlust

Zwei Instanzen sind mit definiertem Informationsverlust zuweisungskompatibel, wenn die zuzuweisende Klasse einer von der zugewiesenen Klasse abgeleiteten Klasse angehört. Alle Daten die in der zugewiesenen Klasse deklariert und somit erforderlich sind, können zugewiesen werden, jedoch werden die in der zuzuweisenden, abgeleiteten Klasse hinzugefügten Attribute und Methoden ignoriert. Beispiel:

## Zuweisungen ohne Typsicherheit

Programmiersprachen, die für die maschinennahe Programmierung konzipiert wurden, wie zum Beispiel C, haben oft gar keine oder nur eine sehr schwache Typprüfung. Diese Toleranz führt leicht zu Programmfehlern.

### Zeiger

In manchen Programmiersprachen, wie zum Beispiel C, ist es erlaubt, beliebige Zeiger einer Zeigervariablen zuzuweisen, ohne dass geprüft wird oder überhaupt geprüft werden kann, ob die Datentypen der referenzierten Daten identisch oder kompatibel sind.

### Wahrheitswerte

In einigen älteren Programmiersprachen, wie zum Beispiel C, gibt es keinen eigenen Datentyp für zweiwertige boolesche Variablen. Zur Behandlung und Verarbeitung entsprechender Information wird dann häufig der ganzzahlige Datentyp mit dem kleinsten Speicherbedarf verwendet, wobei der Zahlenwert null für den Wahrheitswert „Falsch“ und alle anderen Zahlenwerte für den Wahrheitswert „Wahr“ Verwendung finden. Auch hier ergeben sich logische Inkompatibilitäten und somit Komplikationen, da mit binären Werten keine Arithmetik und mit Zahlen keine logischen Verknüpfungen oder logischen Operationen durchgeführt werden können. Im folgenden Beispiel wird dieser Missbrauch verdeutlicht:

Eine eindeutige und korrekte Implementierung könnte wie folgt aussehen:

### Mengen

Sinngemäß gilt das Gleiche für die Verknüpfungen von Mengen. Wenn hier bei den Datentypen und zulässigen Operatoren nicht zwischen Mengen (englisch = Bitsets) und Zahlen unterschieden wird, kommt es wie zum Beispiel bei der Bestimmung von Differenzmengen zu Interpretationsproblemen:

Eine eindeutige und korrekte Implementierung könnte wie folgt aussehen:

