Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Komisches mit variantem record (https://www.delphipraxis.net/209530-komisches-mit-variantem-record.html)

TurboMagic 17. Dez 2021 13:54

Komisches mit variantem record
 
Hallo,

ich nutze einen varianten Record um auch byteweise auf TDateTime zugreifen zu können.
Soweit so gut, Code siehe hier:

Delphi-Quellcode:
/// <summary>
///   Varianter Record für TDateTime um auf das auch byteweise zugreifen zu können
/// </summary>
TVariantDateTime = record
  case Bytewise: Boolean of
    /// <summary>
    ///   Zeitstempel als Zeitstempel
    /// </summary>
    false : (TimeStamp:TDateTime);
    /// <summary>
    ///   Zeitstempel als Bytes
    /// </summary>
    true : (Bytes:array[0..7] of UInt8);
end;

var
  dt:TVariantDateTime;
Wenn ich jetzt mit dem Debugger SizeOf(dt) abfrage kommt immer 16 raus,
statt der erwarteten 8. Frage ich SizeOf(dt.TimeStamp) ab, kommt 8 raus.

Warum?

Grüße
TurboMagic

BerndS 17. Dez 2021 14:06

AW: Komisches mit variantem record
 
Das erste Byte ist wohl Bytewise und bei
Delphi-Quellcode:
  TVariantDateTime = packed record
kommt dann 1 + 8 = 9 raus.
Ohne packed entscheidet die Compilereinstellung Recordfelder ausrichten über die Größe des Records.

TurboMagic 17. Dez 2021 14:15

AW: Komisches mit variantem record
 
Mit dem Packed hast du wohl recht...

Uwe Raabe 17. Dez 2021 14:20

AW: Komisches mit variantem record
 
Du kannst den varianten Teil auch so schreiben, dann kommt als Größe auch 8 heraus:
Delphi-Quellcode:
TVariantDateTime = record
  case Boolean of
    false : (TimeStamp:TDateTime);
    true : (Bytes:array[0..7] of UInt8);
end;

Der schöne Günther 17. Dez 2021 14:22

AW: Komisches mit variantem record
 
Ich würde das aber ehrlich gesagt nicht als varianten Record machen. Eigentlich sind "class helper" dazu die bessere Wahl.

Nicht umsonst haben
Delphi-Quellcode:
Single
und
Delphi-Quellcode:
Double
das auch schon fest eingebaut sodass du z.B. sagen kannst
Delphi-Quellcode:
meinSingle.Bytes[3]
.

TurboMagic 17. Dez 2021 16:37

AW: Komisches mit variantem record
 
Wenn das schon als CLassHelper drin ist noch besser. Stelle dann evtl. morgen darauf um.

himitsu 17. Dez 2021 20:48

AW: Komisches mit variantem record
 
Zitat:

Delphi-Quellcode:
case Bytewise: Boolean of

Jupp, das hier ist auch ein Feld, also ein zusätzliches Byte.
Und duch die Speicherausrichtung {$ALIGN rutscht dein Timestamp eine "ganze" Position weiter, womit der Record dann enorm anwächst.

Bei Packed, wird der Freiraum zwischen diesem Byte und deinem Timestamp weggelassen,
es bleibt aber dennoch ein Byte zuviel.

Zitat:

Delphi-Quellcode:
case Boolean of

Ist nur die Vaianten-Deklaration, ohne dieses Byte;

Delphi-Quellcode:
TVariantDateTime = record
  Bytewise: Boolean;
  case Boolean of
    false : (TimeStamp:TDateTime);
    true : (Bytes:array[0..7] of UInt8);
end;
Deine Variante und diese Variante kann man nutzen, um sich zu merken was man gespeichert hat.

Ähnlich wie beim "richtigen" Delphi-Referenz durchsuchenVariant, welcher intern auch bissl anders ausschaut,
siehe System.pas > TVarData und "Variant type codes" ala varInteger (Delphi) bzw. vt_i4 (WinAPI)


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:50 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz