AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben
Thema durchsuchen
Ansicht
Themen-Optionen

kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

Ein Thema von Amicello · begonnen am 14. Okt 2024 · letzter Beitrag vom 14. Okt 2024
Antwort Antwort
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#1

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 21:59
Bei Packed Records hat mich immer der "Integer of" Teil verwirrt:
Da vermischt du zwei Dinge:
Packed Records sind eigentlich ganz normale Records. Üblicherweise werden die im Speicher (je nach eingestellter Compiler-Option, aber ich gehe von der Voreinstellung aus) an den Wort-Grenzen der gewählten Prozessorarchitektur ausgerichtet (aktuell also 32- oder 64-Bit Wortbreite). Heisst, dass selbst wenn du in einem Record nur ein Byte deklarierst, wird ein nachfolgendes Byte nicht ein Byte weiter im Speicher liegen, sondern ein DWORD oder QWORD weiter.
Wenn du nun einen Record als "packed" deklarierst, wirft der Compiler das über Bord, und das zweite Byte wird tatsächlich nur ein Byte später im Speicher stehen.
Grund ist, dass es üblicherweise schneller und effizienter ist, immer so auf den Speicher zuzugreifen, dass man sich immer an den "natürlichen" Grenzen der Architektur orientiert. Anderenfalls muss hinter den Kulissen immer etwas "gepflückt und geschubst" werden - entweder vom Compiler, oder die CPU macht das selber. Kostet aber halt immer Taktzyklen.
Daher sollte man einen Record nur dann packed deklarieren, wenn es essenziell wichtig ist, dass im Speicher nachher alle Felder des Records dicht an dicht liegen. Ein paar Bytes hier und da "sparen" rechtfertigt das heutzutage meiner Meinung nach nicht mehr.

Das andere sind "Variante Records":
Das ist eine etwas verwirrende Schreibweise, da Delphi sonst kein Vokabular hat, um unterschiedliche Namen für den selben Speicherbereich zu deklarieren. Du sagst hier am Ende nur: Es gibt ein Integer-langes Stück Speicher, und es folgt eine Liste von ebenfalls jeweils insgesamt Integer-langen deklarationen, unter dessen Namen man wahlweise auf diesen Bereich (oder Teilen von diesem) später zugreifen kann.
Die gezeigte Deklaration sagt also:
1) Es gibt ein Stück Speicher der Länge SizeOf(Integer) (was hier allerdings falsch wäre, es müsste "Word" benutzt werden!)
2) Du kannst das ganze Word unter dem Namen "AsWord" erreichen.
3) Du kannst alternativ das erste Byte desselben Words unter dem Namen "x", das andere "y" erreichen.


Zitat:
"Was willst Du damit erreichen?"
Immer zwei Variablen für x/y seperat zu übergeben fand ich umständlich.
Zu dem gehören die für mein Verständnis ja auch logisch zu einer Einheit.

Habt mir sehr weitergeholfen!
Dafür sind definitiv Records, oder besser noch Klassen da! Wenn es dir rein um die "Semantik" geht, sind das die Werkzeuge - sie wurden genau dafür entwickelt!
Rumgefummel an/in internen Strukturen kann - in sehr spezifischen Einzelfällen(!) - Sinn machen, aber das sollte dann seeeehr gut begründet und dokumentiert sein. Deine Motivation würde ich hier keinesfalls als "guten Grund" ansehen können, weil es wie gesagt High-Level Mechanismen gibt, die ganz genau dafür da sind, und Lesbarkeit, Testbarkeit und Debugbarkeit sogar erhöhen, statt quasi komplett zu zerstören.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
10.054 Beiträge
 
Delphi 12 Athens
 
#2

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 22:10
Das ist eine etwas verwirrende Schreibweise, da Delphi sonst kein Vokabular hat, um unterschiedliche Namen für den selben Speicherbereich zu deklarieren.
Nur der Vollständigkeit halber, das hat damit sonst nichts zu tun:
Doch, dafür gibt es absolute.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#3

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 22:41
Das ist eine etwas verwirrende Schreibweise, da Delphi sonst kein Vokabular hat, um unterschiedliche Namen für den selben Speicherbereich zu deklarieren.
Nur der Vollständigkeit halber, das hat damit sonst nichts zu tun:
Doch, dafür gibt es absolute.
Ah okay, ich dachte das ist ein Spezialkonstrukt, dass nur in Siemens SCL existiert. Scheint aber nicht im Kontext von Record-Feldern zu gehen, vermutlich dann eher ein Relikt aus Turbo Pascal Zeiten oder?
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.547 Beiträge
 
Delphi 12 Athens
 
#4

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 22:54
Ja, absolute sagt quasi, dass die neue Variable keinen eigenen Speicher hat, sondern an Stelle einer anderen Variable liegt. (sie darf nur nicht größer sein)
Aufpassen muß man mit managed Typen (String, dynamic Array, Variant, Interface usw.), um die Speicherverwaltung nicht zu schrotten.

Nutzen kann man es super für indirekte "Casts"
oder als "Alias", um einen anderen Namen für eine andere Variable nutzen zu können. (z.B. kürzer oder bei Konflikten im nachfolgenden Code)


Bei Varianten Records passt der Compiler auf und lässt solche Typen erst garnicht zu

Scheint aber nicht im Kontext von Record-Feldern zu gehen
Nicht "innerhalb" von Records. Aber dort gibt es ja die Varianten-Records.
Alternativ kann man auch mit Methoden/Property arbeiten.

Delphi-Quellcode:
type
  TMyRecord = record
    dooferName: Integer;
    property Schöner: Integer read dooferName write dooferName; // oder für Konvertierung, z.B. von DOS-TimeStamp zu TDateTime
  end;

  TMyRecord = record
  private
    FSicher: Integer;
  public
    property NurReadOnly: Integer read FSicher;
  end;

  TMyRecord = record
  private
    FSicher: Integer;
    procedure SetSicher(Value: Integer); // hier drin z.B. eine Zugriffsprüfung oder ein OnChange-Event
  public
    property Öffentlich: Integer read FSicher write SetSicher;
  end;
Zitat:
Delphi-Quellcode:
  TSearchRec = record
  private
    function GetTimeStamp: TDateTime;
  public
    Time: Integer platform deprecated; // Platform, weil das z.B. unter im Android oder MacOS anders aussieht.
    
    property TimeStamp: TDateTime read GetTimeStamp; // Das Property geht dann intern auf das Jeweilige, also für uns egal für was kompiliert wird.
  end;
Delphi-Referenz durchsuchenTSearchRec.TimeStamp
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (14. Okt 2024 um 23:14 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.547 Beiträge
 
Delphi 12 Athens
 
#5

AW: kleine Datentypen (BYTE) zusammenfassend als z.B. WORD/Integer übergeben

  Alt 14. Okt 2024, 22:40
Packed Records sind eigentlich ganz normale Records. Üblicherweise werden die im Speicher (je nach eingestellter Compiler-Option, aber ich gehe von der Voreinstellung aus) an den Wort-Grenzen der gewählten Prozessorarchitektur ausgerichtet (aktuell also 32- oder 64-Bit Wortbreite). Heisst, dass selbst wenn du in einem Record nur ein Byte deklarierst, wird ein nachfolgendes Byte nicht ein Byte weiter im Speicher liegen, sondern ein DWORD oder QWORD weiter.
Jo, Packed-Records sind einfach nur Records mit {$ALIGN 1}
maximale Ausrichtung an 1 Byte-Grenze

Gleichgroße Typen folgen immer einander.
folgt ein größerer Typ, dann wird er an "seiner" Größe ausgerichtet, oder maximal so viel, wie vorgegeben.

Also normal wird ein Word an 2 Byte ausgerichtet,
mit einer Lücke, wenn davor nur 1 Byte war.

Packed-Records oder Records mit einer definierten Ausrichtung braucht man nur, wenn der Records prozessübergreifend gespeichert/übertragen wird.

Innerhalb des selben Prozesses, ist es "optimaler", wenn ordentlich ausgerichtet wird, damit möglichst effizient auf den Speicher zugegriffen werden kann,
außer, es geht um maximale Speicher-Ersparnis. (meistens ist Effzienz aber das Wichtigere)


Zitat:
Integer of
Hier ist eigentlich CASE das wichtige Wort.
CASE OF

Dawzischen steht ein Typ, für die Zuordnung der CASES, welches auch eine "Variable" sein kann.
Delphi-Quellcode:
case Boolean of
  True: ( ... );
  False: ( ... );

case Char of
  'A': ( ... );
  'B': ( ... );

case Integer of
  0: ( ... );
  1: ( ... );

case Was: Integer of
  0: ( ... );
  1: ( ... );

// das Vorhergehende entspricht quasi Diesem, also mit einer Variable, in der man speichern kann (nicht muß), welcher Teil gültig ist.
Was: Integer;
case Integer of
  0: ( ... );
  1: ( ... );
Das nennt sich Variante-Records, also wo quasi verschiedene "Varianten" der Speicherbenennug übereinander liegen.
Auch andere Sprachen (C++) kennen sowas.
PS: Der Typ Variant nutzt intern sowas, um z.B. einen Integer oder einen String/PChar auf der selben Stelle zu speichern.

Das einzige Problem für Delphi ist, dass dem CASE das eigene END fehlt
und deswegen im Delphi/Pascal der Variante Block ausschließlich am Ende des Records stehen kann.
In C++ kann er auch mittendrin sein, was eine Konvertierung von Code nicht erleichtert.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (14. Okt 2024 um 22:50 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:55 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