Einzelnen Beitrag anzeigen

choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#9

Re: Compiler weiss nicht welcher Typ?

  Alt 20. Jan 2004, 12:28
Der Delphi-Compiler ordnet bei der Übesetzung jedem Ausdruck einen Typen zu, um überprüfen zu können, ob Zuweisungen zulässig sind, ob übergebene Parameter einem kompatiblen Typen entsprechen, der ggf Konvertiert werden kann, etc.
So hat zB der konstante Ausdruck
189+4 den impliziten Typ Byte zugeordnet. Bei einem Ausdruck der Form
4+3 jedoch den Typ 0..127 (nachzulesen in der OH "Echte Konstanten").
Bei der Deklaration von Variablen wird idR explizit ein Typ angegeben, zB
Delphi-Quellcode:
var
  myInt : Integer;
und der Compiler ist dank dieser Information später in der Lage zu entscheiden, ob eine Zuweisung der Form
myInt:= 189+4; zulässig ist (nachzulesen in der OH unter "Typkomatiblität"). Darüber hinaus kann er nur durch die Angabe des Typs den Operator (nein, es ist keine Funktion) SizeOf verwenden, also die Größe in Bytes zu einem Datentypen ermitteln, obwohl dieser Information nicht zu jeder Variablen abgelegt wird. Stattdessen greift er zu diesem Zweck auf seine eigene "Buchführung" zurück...

Es ist möglich, ohne einen benannten Typen, eine Variable zu deklarieren:
Delphi-Quellcode:
var
  myVar: record
    AField: Integer;
  end;
Damit der Compiler später zB in der Lage ist, zu erkennen, dass die Zuweisung
myVar:= '6*9=42'; ungültig ist, aber auch um Konstrukte der Art
FillChar(myVar, SizeOf(myVar), 0); zu ermöglichen, muss der Compiler der Variablen myVar einen Typen zuordnen.
Aus Mangel an Unterstützung seitens des Programmiers ist der Compiler an dieser Stelle gezwungen, selbst einen Typen zu erstellen und zu ihm die notwendigen Informationen ablegen, allerdings verwendet er hierzu keinen für den Programmierer zugänglichen Namen und dieser Typ dient nur dem Compiler zur Übersetzungszeit. Wollte der Programmierer mit dieser Information arbeiten hätte er schließelich einen Typen in der Form
Delphi-Quellcode:
type
  TMyType = record
    AField: Integer;
  end;
var
  myVar: TMyType;
benannt

Wenn Du hingegen zweimal einen anonymen Typen erstellst, zB mit
Delphi-Quellcode:
var
  aString: string[10];
  anotherString: string[10];
wird der Compiler zweimal einen eigenen Typen erstellen, der nicht identisch ist mit dem Anderen (siehe hierzu die OH "Typenidentität"). Welche Konsequenzen das für Dein Programm, zB bei Zuweisungen der Art
aString:= anotherString hat, kannst Du in der OH unter "Zuweisungskompatibilität" nachlesen.

BTW: Dies ist auch der Grund warum Signaturen von Methoden, Funktionen und Prozeduren in der Form
procedure MyProc(var AValue: record AField: Integer; end;); unzulässig sind: Es gibt keinen kompatiblen Datentypen...


Das Prinzip, der anonymen Datentypen ist in anderen Sprachen noch weiter vertreten, bei denen man zB ein Exemplar einer Klasse (Objekt), die von einer anderen Erbt und zu der man ad-hoc eine Methode überschreibt, erzeugen kann ohne die Klasse zu benennen
Zum Verständnis in Pseudo-PascalCode:
Delphi-Quellcode:
var
  myObject: TMyClass;
  anotherObject: TMyClass;
begin
  myObject:= TMyClass.Create(Self);
  Showmessage(IntToStr(myObject.GetValue)); // e.g. '5'

  anotherObject:= (class(TMyClass)
    function GetValue: Integer; overload;
    begin
      Result:= (inherited GetValue) + 23;
    end; ).Create(Self);
  Showmessage(IntToStr(anotherObject.GetValue)); // '28'
wobei folgende Aussagen wahr wären:
Delphi-Quellcode:
anotherObject.InheritsFrom(TMyClass);
anotherObject.ClassType<>myObject.ClassType;
anotherObject is TMyClass;
gruß, choose
  Mit Zitat antworten Zitat