nested unions and structs
Regan Heath
regan at netwin.co.nz
Thu Apr 27 14:36:26 PDT 2006
On Thu, 27 Apr 2006 18:28:05 +0000 (UTC), Alberto Simon
<Alberto_member at 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
More information about the Digitalmars-d
mailing list