digitalmars.D.bugs - struct.sizeof is wrong when the struct contains a union
- Geoff Hickey (25/25) Dec 02 2004 Using dmd v.108 on WinXP, structures that contain named unions don't hav...
- Regan Heath (36/52) Dec 02 2004 Actually, you're not declaring an instance of your union, only the
- Geoff Hickey (15/29) Dec 02 2004 Ah. Gotcha. That being the case, shouldn't the compiler complain when do...
- Regan Heath (33/71) Dec 02 2004 Yes. I think you've found a bug.
- Thomas Kuehne (15/42) Dec 03 2004 -----BEGIN PGP SIGNED MESSAGE-----
- Simon Buchan (17/31) Dec 03 2004 Walter, if you're listening, is there any reason to
- Walter (3/5) Dec 04 2004 Anonymous structs make them unnecessary.
Using dmd v.108 on WinXP, structures that contain named unions don't have the correct size. In the example below, the size of the structure type "test" is reported as 1, not 4 as it should be; and the size of the union "junk" inside it is 4, as expected. Declaring an instance of the structure and taking the size of it gives the same result. If the union is made anonymous, the problem disappears. /* * Example of structure size error: */ import std.stdio; struct test { union junk { uint a; uint b; } } int main() { writefln( "Struct size: %s", test.sizeof ); writefln( "Union size: %s", test.junk.sizeof ); assert( test.sizeof >= test.junk.sizeof ); return 0; }
Dec 02 2004
On Thu, 2 Dec 2004 22:01:10 +0000 (UTC), Geoff Hickey <Geoff_member pathlink.com> wrote:import std.stdio; struct test { union junk { uint a; uint b; } } int main() { writefln( "Struct size: %s", test.sizeof ); writefln( "Union size: %s", test.junk.sizeof ); assert( test.sizeof >= test.junk.sizeof ); return 0; }Actually, you're not declaring an instance of your union, only the definition, instead try: import std.stdio; struct test { union junk { uint a; uint b; } junk a; } int main() { writefln( "Struct size: %s", test.sizeof ); writefln( "Union size: %s", test.junk.sizeof ); assert( test.sizeof >= test.junk.sizeof ); return 0; } Note: When you write: union junk { uint a; uint b; } you are not declaring an instance of a union, but instead the definition of one, therefore in order to actually put one into your struct you have to declare an instance of one, thus the line: junk a; Anonymous unions are allowed and of course declare an instance instead of a definition. This can definately be a little confusing at first as it's not identical to C/C++. I think this should go into the FAQ (if it's not already) Regan
Dec 02 2004
In article <opsieivo1m23k2f5 ally>, Regan Heath says...Note: When you write: union junk { uint a; uint b; } you are not declaring an instance of a union, but instead the definition of one, therefore in order to actually put one into your struct you have to declare an instance of one, thus the line: junk a; Anonymous unions are allowed and of course declare an instance instead of a definition. This can definately be a little confusing at first as it's not identical to C/C++. I think this should go into the FAQ (if it's not already) ReganAh. Gotcha. That being the case, shouldn't the compiler complain when do this?: struct test { union junk { uint a; uint b; } } int main() { test tv; tv.junk.a = 1; } But it doesn't; this program compiles and runs. - Geoff Hickey
Dec 02 2004
On Thu, 2 Dec 2004 23:11:21 +0000 (UTC), Geoff Hickey <Geoff_member pathlink.com> wrote:In article <opsieivo1m23k2f5 ally>, Regan Heath says...Yes. I think you've found a bug.Note: When you write: union junk { uint a; uint b; } you are not declaring an instance of a union, but instead the definition of one, therefore in order to actually put one into your struct you have to declare an instance of one, thus the line: junk a; Anonymous unions are allowed and of course declare an instance instead of a definition. This can definately be a little confusing at first as it's not identical to C/C++. I think this should go into the FAQ (if it's not already) ReganAh. Gotcha. That being the case, shouldn't the compiler complain when do this?:struct test { union junk { uint a; uint b; } } int main() { test tv; tv.junk.a = 1; } But it doesn't; this program compiles and runs.Indeed, and produces some odd (but not unexpected) results: eg.. import std.stdio; struct test { union junk { uint a; uint b; } } int main() { test tv; int padding; padding = 0; tv.junk.a = 1; tv.junk.b = 2; writef(tv.junk.a,",",tv.junk.b,",",padding,"\n"); printf("0x%X,0x%X,0x%X,0x%X\n",&tv,&tv.junk.a,&tv.junk.b,&padding); return 0; } I was expecting the 'padding' variable to be stomped on by the assignment to 'tv.junk.a' and/or 'tv.junk.b' because the struct 'tv' has reportedly got a sizeof 1 and a uint has a sizeof 4. However it seems the compiler has placed some padding between 'tv' and 'padding'. Regan
Dec 02 2004
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Geoff Hickey schrieb am Thu, 2 Dec 2004 23:11:21 +0000 (UTC):In article <opsieivo1m23k2f5 ally>, Regan Heath says...you are not declaring an instance of a union, but instead the definition of one, therefore in order to actually put one into your struct you have to declare an instance of one, thus the line: junk a; Anonymous unions are allowed and of course declare an instance instead of a definition. This can definately be a little confusing at first as it's not identical to C/C++. I think this should go into the FAQ (if it's not already)Ah. Gotcha. That being the case, shouldn't the compiler complain when do this?: struct test { union junk { uint a; uint b; } } int main() { test tv; tv.junk.a = 1; } But it doesn't; this program compiles and runs.Added to DStress as: http://svn.kuehne.cn/dstress/nocompile/union_12.d http://svn.kuehne.cn/dstress/nocompile/union_13.d http://svn.kuehne.cn/dstress/nocompile/union_14.d http://svn.kuehne.cn/dstress/nocompile/union_15.d Thomas -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.9.12 (GNU/Linux) iD8DBQFBsHDX3w+/yD4P9tIRApIeAKC9yYBq8ugi7iPf+ssG88+W88xv6wCfR6wc bMQY1ou7k1QqoWXWg4T2ewE= =rwRa -----END PGP SIGNATURE-----
Dec 03 2004
On Fri, 03 Dec 2004 11:17:38 +1300, Regan Heath <regan netwin.co.nz> wrote: <snip>Note: When you write: union junk { uint a; uint b; } you are not declaring an instance of a union, but instead the definition of one, therefore in order to actually put one into your struct you have to declare an instance of one, thus the line: junk a; Anonymous unions are allowed and of course declare an instance instead of a definition. This can definately be a little confusing at first as it's not identical to C/C++. I think this should go into the FAQ (if it's not already) ReganWalter, if you're listening, is there any reason to not allow struct {<body>} <instance>;? Now I have nothing against forbidding defining and instancing structs at the same time, but to not allow unnamed struct instances? That's just weird. -- "Unhappy Microsoft customers have a funny way of becoming Linux, Salesforce.com and Oracle customers." - www.microsoft-watch.com: "The Year in Review: Microsoft Opens Up" "Changes/Additions -------------------------------------------------------------------------------- HL2DM released! " - HL2DM changelog - ME
Dec 03 2004
"Simon Buchan" <currently no.where> wrote in message news:opsifsjacvjccy7t simon.homenet...Walter, if you're listening, is there any reason to not allow struct {<body>} <instance>;?Anonymous structs make them unnecessary.
Dec 04 2004