Hallo! Kann jemand von euch erklären, wieso typisierte Konstanten in Delphi so restriktiv sind?
Beispiel:
Delphi-Quellcode:
type
TFourCC = array [0..3] of AnsiChar;
TChunkHeader = packed record
ID: TFourCC;
Size: Cardinal;
end;
const
RiffConst = 'RIFF'; // untypisiert
Riff4CC: TFourCC = 'RIFF';
RiffStr: AnsiString = 'RIFF';
const // oder auch var
DefaultHeader0: TChunkHeader = (ID: 'RIFF'; Size: 0); // funktioniert
DefaultHeader1: TChunkHeader = (ID: RiffConst; Size: 0); // funktioniert
DefaultHeader2: TChunkHeader = (ID: Riff4CC; Size: 0); // E2026: Constant expression expected
DefaultHeader3: TChunkHeader = (ID: RiffStr; Size: 0); // E2026: Constant expression expected
DefaultHeader4 = DefaultHeader0; // E2026: Constant expression expected
DefaultHeader5: TChunkHeader = DefaultHeader0; // "(" expected
Dass DefaultHeader3 nicht geht, akzeptiere ich ja, denn TFourCC ist nicht zuweisungskompatibel mit AnsiString (von array of [
Ansi]Char nach [
Ansi]String geht, da hat Delphi ein paar nette automatische Funktionen, aber von String nach array of Char geht verständlicherweise nicht).
Aber dass DefaultHeader2 nicht funktioniert, finde ich schon sehr seltsam, denn die Typen sind ja absolut identisch.
Was denkt ihr darüber? Sollten solche Konstrukte erlaubt sein oder nicht? Sind sie das vielleicht schon in den neuen Versionen > XE6?
Kleines Detail am Rande, das mit der Frage nichts zu tun hat, aber ganz interessant ist, wenn man gerne schaut, was Delphi hinter den Kulissen macht:
Delphi-Quellcode:
procedure Test1(out ChunkHeader: TChunkHeader);
begin
ChunkHeader.ID := RiffConst; // funktioniert
// RiffConst = 'RIFF' wird hier als DWORD im Codesegment (.text) gespeichert,
// genauer gesagt unmittelbar an der Adresse nach dieser Prozedur!
end;
procedure Test2(out ChunkHeader: TChunkHeader);
begin
ChunkHeader.ID := Riff4CC; // funktioniert
// Riff4CC = 'RIFF' wird hier ganz normal als DWORD im Datensegment (.data) gespeichert
end;