digitalmars.D - nested unions and structs
- Alberto Simon (24/24) Apr 27 2006 The union DWord below does not product the expected union, Data isn't at...
- Oskar Linde (10/36) Apr 27 2006 On what platform & compiler? On Linux dmd 0.154 they are for me:
- Alberto Simon (8/44) Apr 27 2006 It looks like I didn't explain myself. I expect that when I declare a DW...
- Oskar Linde (4/54) Apr 27 2006 No, that is not correct. &Dword.LowerWord should be +4 bytes from
- Regan Heath (94/103) Apr 27 2006 For me, LowerWord is 2 bytes _after_ Data and it's there because
- Alberto Simon (2/18) Apr 27 2006 Thanks a lot, in the end, that was the issue.
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
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
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:Regards, Alberto Simon (20y student)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
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. /OskarIn article <e2q4a7$ljq$1 digitaldaemon.com>, Oskar Linde says...Alberto Simon wrote:Regards, Alberto Simon (20y student)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
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
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:Thanks a lot, in the end, that was the issue.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. ...
Apr 27 2006