www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - nested unions and structs

reply Alberto Simon <Alberto_member pathlink.com> writes:
The union DWord below does not product the expected union, Data isn't at the
same address as the union start address is... What should I do to correct that??

public union Word
{
// Atributos

struct
{
public ubyte Low;
public ubyte High;
}
public ushort Data;
}

public union DWord
{
// Atributos

public uint Data;
struct
{
public Word HigherWord;
public Word LowerWord;
};
}

Regards,
Alberto Simon
Apr 27 2006
parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Alberto Simon wrote:
 The union DWord below does not product the expected union, Data isn't at the
 same address as the union start address is... What should I do to correct
that??
 
 public union Word
 {
 // Atributos
 
 struct
 {
 public ubyte Low;
 public ubyte High;
 }
 public ushort Data;
 }
 
 public union DWord
 {
 // Atributos
 
 public uint Data;
 struct
 {
 public Word HigherWord;
 public Word LowerWord;
 };
 }

On what platform & compiler? On Linux dmd 0.154 they are for me: Word w; DWord d; writefln("%s %s",&d,&(d.Data)); writefln("%s %s",&w,&(w.Data)); Prints: bfffed24 bfffed24 bfffed20 bfffed20 /Oskar
Apr 27 2006
parent reply Alberto Simon <Alberto_member pathlink.com> writes:
It looks like I didn't explain myself. I expect that when I declare a DWord
union and try to access its fields, Data should have the same address LowerWord
has and the same address Low on LowerWord has, but that does not happen, Data
instead is 4 bytes after LowerWord, and that ticks me, since all fields of an
union should start at the same address.

In article <e2q4a7$ljq$1 digitaldaemon.com>, Oskar Linde says...
Alberto Simon wrote:
 The union DWord below does not product the expected union, Data isn't at the
 same address as the union start address is... What should I do to correct
that??
 
 public union Word
 {
 // Atributos
 
 struct
 {
 public ubyte Low;
 public ubyte High;
 }
 public ushort Data;
 }
 
 public union DWord
 {
 // Atributos
 
 public uint Data;
 struct
 {
 public Word HigherWord;
 public Word LowerWord;
 };
 }

On what platform & compiler? On Linux dmd 0.154 they are for me: Word w; DWord d; writefln("%s %s",&d,&(d.Data)); writefln("%s %s",&w,&(w.Data)); Prints: bfffed24 bfffed24 bfffed20 bfffed20 /Oskar

Regards, Alberto Simon (20y student)
Apr 27 2006
next sibling parent Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Alberto Simon wrote:
 It looks like I didn't explain myself. I expect that when I declare a DWord
 union and try to access its fields, Data should have the same address LowerWord
 has and the same address Low on LowerWord has, but that does not happen, Data
 instead is 4 bytes after LowerWord, and that ticks me, since all fields of an
 union should start at the same address.

No, that is not correct. &Dword.LowerWord should be +4 bytes from &DWord.Data. The anonymous struct makes sure of that. /Oskar
 
 In article <e2q4a7$ljq$1 digitaldaemon.com>, Oskar Linde says...
 Alberto Simon wrote:
 The union DWord below does not product the expected union, Data isn't at the
 same address as the union start address is... What should I do to correct
that??

 public union Word
 {
 // Atributos

 struct
 {
 public ubyte Low;
 public ubyte High;
 }
 public ushort Data;
 }

 public union DWord
 {
 // Atributos

 public uint Data;
 struct
 {
 public Word HigherWord;
 public Word LowerWord;
 };
 }

Word w; DWord d; writefln("%s %s",&d,&(d.Data)); writefln("%s %s",&w,&(w.Data)); Prints: bfffed24 bfffed24 bfffed20 bfffed20 /Oskar

Regards, Alberto Simon (20y student)

Apr 27 2006
prev sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 27 Apr 2006 18:28:05 +0000 (UTC), Alberto Simon  
<Alberto_member pathlink.com> wrote:
 It looks like I didn't explain myself. I expect that when I declare a  
 DWord
 union and try to access its fields, Data should have the same address  
 LowerWord
 has and the same address Low on LowerWord has, but that does not happen,  
 Data
 instead is 4 bytes after LowerWord, and that ticks me, since all fields  
 of an
 union should start at the same address.

For me, LowerWord is 2 bytes _after_ Data and it's there because HigherWord aligns with Data and LowerWord comes _after_ HigherWord in the anonymous struct in DWord. In other words it's all working correctly as far as I can see. If you want LowerWord and Data to align you have to reverse the order of LowerWord and HigherWord, eg. public union DWord { public uint Data; struct { public Word LowerWord; public Word HigherWord; }; } Here is a semi-graphical representation of the current memory locations. public union Word { struct { public ubyte Low; public ubyte High; } public ushort Data; } public union DWord { public uint Data; struct { public Word HigherWord; public Word LowerWord; }; } import std.stdio; void main() { Word w; DWord d; writefln("public union Word { ",&w); writefln("\tstruct {"); writefln("\t\tpublic ubyte Low; ",&w.Low); writefln("\t\tpublic ubyte High; ",&w.High); writefln("\t}"); writefln("\tpublic ushort Data; ",&w.Data); writefln("}"); writefln("public union DWord { ",&d); writefln("\tpublic uint Data; ",&d.Data); writefln("\tstruct {"); writefln("\t\tpublic Word HigherWord { ",&d.HigherWord); writefln("\t\t\tpublic ushort Data; ",&d.HigherWord.Data); writefln("\t\t\tstruct {"); writefln("\t\t\t\tpublic ubyte Low; ",&d.HigherWord.Low); writefln("\t\t\t\tpublic ubyte High; ",&d.HigherWord.High); writefln("\t\t\t}"); writefln("\t\t}"); writefln("\t\tpublic Word LowerWord { ",&d.LowerWord); writefln("\t\t\tpublic ushort Data; ",&d.LowerWord.Data); writefln("\t\t\tstruct {"); writefln("\t\t\t\tpublic ubyte Low; ",&d.LowerWord.Low); writefln("\t\t\t\tpublic ubyte High; ",&d.LowerWord.High); writefln("\t\t\t}"); writefln("\t\t}"); writefln("\t}"); writefln("}"); } Results: public union Word { 12FF30 struct { public ubyte Low; 12FF30 public ubyte High; 12FF31 } public ushort Data; 12FF30 } public union DWord { 12FF34 public uint Data; 12FF34 struct { public Word HigherWord { 12FF34 public ushort Data; 12FF34 struct { public ubyte Low; 12FF34 public ubyte High; 12FF35 } } public Word LowerWord { 12FF36 public ushort Data; 12FF36 struct { public ubyte Low; 12FF36 public ubyte High; 12FF37 } } } } Regan
Apr 27 2006
parent Alberto Simon <Alberto_member pathlink.com> writes:
In article <ops8orm0db23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Thu, 27 Apr 2006 18:28:05 +0000 (UTC), Alberto Simon  
<Alberto_member pathlink.com> wrote:
 It looks like I didn't explain myself. I expect that when I declare a  
 DWord
 union and try to access its fields, Data should have the same address  
 LowerWord
 has and the same address Low on LowerWord has, but that does not happen,  
 Data
 instead is 4 bytes after LowerWord, and that ticks me, since all fields  
 of an
 union should start at the same address.

For me, LowerWord is 2 bytes _after_ Data and it's there because HigherWord aligns with Data and LowerWord comes _after_ HigherWord in the anonymous struct in DWord. In other words it's all working correctly as far as I can see. ...

Thanks a lot, in the end, that was the issue.
Apr 27 2006