AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Zugriff auf Variante Teile in Record-Typen
Thema durchsuchen
Ansicht
Themen-Optionen

Zugriff auf Variante Teile in Record-Typen

Ein Thema von ma2xx · begonnen am 25. Nov 2005 · letzter Beitrag vom 28. Nov 2005
Antwort Antwort
Seite 2 von 3     12 3      
NicoDE
(Gast)

n/a Beiträge
 
#11

Re: Zugriff auf Variante Teile in Record-Typen

  Alt 25. Nov 2005, 15:11
Zitat von ma2xx:
(gibt es auch andere Unions?)
Jupp:
Code:
union {
    int    T1;
    double T2;
} u1;
Würde übersetzt werden mit:
Delphi-Quellcode:
u1: record
  case Boolean of
    False: (T1: Integer);
    True: (T2: Double);
{ end; }
end;
...unbenannte Unions sind eine Strafe für jeden Entwickler der C/C++ nach Delphi portieren muss...
  Mit Zitat antworten Zitat
ma2xx

Registriert seit: 25. Nov 2005
22 Beiträge
 
#12

Re: Zugriff auf Variante Teile in Record-Typen

  Alt 25. Nov 2005, 15:25
Es ist offensichtlich, dass das Problem die Speicherausrichtung ist.
Delphi-Quellcode:
TTest = record
    case Typ:Boolean of
    false: (T1 :Integer);
    true: (T2 :Double);
  end;
- TTest wird je nach Compilerschalter gerade ausgerichtet (Startadresse)
- Typ (Boolean) ist 1Byte lang (wäre es ein Aufzählungstyp, dann auch 1Byte, es sei denn man aktiviert {$Z4} (4Bytes))
- Es folgt speicherüberlappend T1 (4Bytes lang) und T2 (8Bytes lang) -> nur warum nicht an der gleichen Anfangsadresse???

@Nico Bendlin
Der Code in C++ sieht wie folgt aus (wenn ich mich nicht irre)
Code:
struct {
  Bool     Typ;
  union {
    int    T1;
    double T2;
  };
} TTest;
Jedenfalls ist hier die Adresse von T1 == Adresse von T2!
Siehe hierzu: MSDN Figure 8.1 Storage of Data in NumericType Union
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#13

Re: Zugriff auf Variante Teile in Record-Typen

  Alt 25. Nov 2005, 16:02
Zitat von ma2xx:
nur warum nicht an der gleichen Anfangsadresse?
Weil der Delphi-Compiler den varianten Teil der Struktur offensichtlich nicht als Einheit betrachtet und die Ausrichtung jeweils einzeln für die Mitglieder der 'Union' berechnet (dies ist wahrscheinlich nicht das, was die meisten Entwickler erwarten würden - kurz, man könnte es als Bug bezeichnen (ich kenne die Delphi-Dokumentation nicht auswendig )).

Zitat von ma2xx:
Der Code in C++ sieht wie folgt aus (wenn ich mich nicht irre)
Ja, leider...
...in einer Typ-Definition haben anonyme Unions eigentlich nichts zu suchen.
( siehe http://msdn.microsoft.com/library/de...m/class_33.asp )

Es wäre besser gewesen, wenn die Deklaration so ausgesehen hätte:
Code:
typedef struct tag_TTest {
  bool     Typ;
  union {
    int    T1;
    double T2;
  } u1;
} TTest, * PTest;
Wie auch immer, es hält dich niemand davon ab, die Struktur in Delphi anders zu übersetzen (zum Beispiel mit u1 als inline-record)...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Zugriff auf Variante Teile in Record-Typen

  Alt 25. Nov 2005, 16:03
Zitat von ma2xx:
nur warum nicht an der gleichen Anfangsadresse???
Weil die vermutlich an einer ihrem Typ entsprechenden Stelle ausgerichtet werden. (siehe meinen letzten Beitrag)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
ma2xx

Registriert seit: 25. Nov 2005
22 Beiträge
 
#15

Re: Zugriff auf Variante Teile in Record-Typen

  Alt 25. Nov 2005, 16:30
Nunja, wir kommen wohl nicht weiter ...

Mein Eindruck ist, dass hier ein Delphi-Bug vorliegt.
Meine Versuche zeigten, dass die Anfangsadressen von T1 und T2 abhängig von der Position des Typ sind, egal ob der Typ vor der case oder in der case steht. Es ist auch egal wie lang die varianten Teile des Record sind.
Es bleibt also als Workaround nur das Einfügen von Bytes bis ein gerade Adresse vorliegt (getestet und OK) oder die Verwendung eines weiteren lokalen record um die case (getestet und OK, aber dadurch lokaler Bezeichner -> umständlich).
Die Deklaration der union in C++ ist davon unabhängig. Hier liegen in allen Varianten gleiche Adressen vor!

Vielleicht werde ich mal bei Borland nachfragen ...
Danke für die Diskussion.
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#16

Re: Zugriff auf Variante Teile in Record-Typen

  Alt 25. Nov 2005, 22:53
Moin ma2xx,

je nach Delphi-Version könntest Du es auch einmal mit $A bzw. $ALIGN probieren den Compiler zum "mitspielen" zu bewegen.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#17

Re: Zugriff auf Variante Teile in Record-Typen

  Alt 27. Nov 2005, 17:11
Zitat von Christian Seehase:
je nach Delphi-Version könntest Du es auch einmal mit $A bzw. $ALIGN probieren den Compiler zum "mitspielen" zu bewegen.
Bringt in dem Fall nichts (der Bug entsteht dadurch, dass die Ausrichtung für jedes Mitglied des varianten Teils der Struktur neu berechnet wird...).
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Zugriff auf Variante Teile in Record-Typen

  Alt 27. Nov 2005, 21:30
{$A-}, {$A1}, oder {$ALIGN OFF} sollte wohl helfen?
Zitat von OH:
Wenn ein Record-Typ mit dem voreingestellten Status {$A+} deklariert wird und die Deklaration nicht den Modifizierer packed enthält, handelt es sich um einen ungepackten Record-Typ. Die Felder des Records werden so ausgerichtet, dass die CPU möglichst effizient darauf zugreifen kann. Die Ausrichtung hängt von den Typen der einzelnen Felder ab und davon, ob Felder zusammen deklariert werden. Jeder Datentyp besitzt eine implizite Ausrichtungsmaske, die vom Compiler automatisch berechnet wird. Sie kann die Werte 1, 2, 4 oder 8 haben und entspricht dem Byte-Raster, in dem ein Wert dieses Typs für den optimalen Zugriff im Speicher angeordnet werden muss. Die folgende Tabelle enthält die Ausrichtungsmasken für alle Datentypen.
...
Wenn ein Record-Typ mit dem Status {$A–} deklariert wird oder die Deklaration den Modifizierer packed enthält, werden die Felder des Records nicht ausgerichtet, sondern einfach an aufeinander folgenden Offsets abgelegt.
Themen in der OH > "$ALIGN" oder auch "Felder ausrichten (Compiler-Direktive)"
wobei hierfür der Abschitt "Record-Typen" (wird von dem oben angegebenen Abschitt weiterverlinkt) zutreffender ist.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#19

Re: Zugriff auf Variante Teile in Record-Typen

  Alt 28. Nov 2005, 09:00
Zitat von himitsu:
{$A-}, {$A1}, oder {$ALIGN OFF} sollte wohl helfen?
Nope, weil die Aufgabe war/ist, ohne Hilfsvariablen die selbe Ausrichtung wie in der Referenzstruktur zu erreichen (und das geht, wie oben bereits mehrmals festgestellt, nicht).
  Mit Zitat antworten Zitat
ma2xx

Registriert seit: 25. Nov 2005
22 Beiträge
 
#20

Re: Zugriff auf Variante Teile in Record-Typen

  Alt 28. Nov 2005, 09:28
Ich bin für neue Ideen immer dankbar ...
Wenn ich folgenden Code teste ...
Delphi-Quellcode:
TTest = record
    case Typ:Boolean of
{$A-}
    false: (T1 :Integer);
    true: (T2 :Double);
{$A+}
end;
... dann erhalte ich tatsächlich gleiche Adressen für T1 und T2:
@Test.T1: $12F3D5
@Test.T2: $12F3D5
Diese Vorgehensweise macht prinzipiell Sinn, wenn man sich als Programmierer dem Problem unterschiedlicher Adressen für die varianten Teile des Records bewusst ist (zumindest muss ich nicht alle Records manuell nachrechnen). Nur jetzt muss man noch klären, ob C++ für die varianten Teile immer eine gerade (ausgerichtete) Adresse standardmäßig verlangt, denn wie unschwer zu erkennen, sind in meinem Beispiel die Adressen ungerade. Ich werde das auch nochmal klären ...
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 06:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz