digitalmars.D - DMD-64 2.062 and GCC can't pass >8byte structs?
- E.S. Quinn (61/61) Apr 13 2013 Hi! I've been helping with some code to interface to a C library,
- E.S. Quinn (42/42) Apr 13 2013 Er, my apologies. The code on that post won't actually do what
- Dicebot (1/1) Apr 14 2013 http://d.puremagic.com/issues/show_bug.cgi?id=5570
Hi! I've been helping with some code to interface to a C library, and I think I've discovered a bit of a hangup in the 64-bit linux version of DMD. If a struct is eight bytes or less (the size of two uints), it can be passed just fine between D and C code, but if it's any larger than that, the data gets messed up somewhere along the way. This doesn't happen when the code is compiled in 32-bit mode (with -m32) Here's some example code to trigger the bug: structyc.c: ----- #include <stdio.h> struct passingstruct { unsigned int a; unsigned int b; int c; }; void printatest (struct passingstruct value) { printf ("hello!\n"); printf ("%u %u %d\n", value.a, value.b, value.c); } ----- structyd.d: ------ import std.stdio; struct passingstruct { uint a; uint b; int c; void printme () { writefln ("%d %d", a, b); } } int main (char[][] args) { auto thingy = passingstruct( 300, 200, 0); writefln ("%u %u %d", test.a, test.b, test.c); printatest (test); return 0; } extern (C) { void printatest (passingstruct value); } ------- When compiled and linked in 64-bit mode, it produces this output: 300 200 0 hello! 394682976 32695 402542592 However, 32-bit mode produces the expected output: 300 200 0 hello! 300 200 0 Additionally, if the third element (.c) is taken out of the "testman" struct, or if b and c are made ushort or ubyte, the program works fine in 64-bit mode. GDC(an admittedly out-of-date version--ubuntu only packages 4.6.3) also successfully passes the whole struct in 64bit mode.
Apr 13 2013
Er, my apologies. The code on that post won't actually do what it's supposed to. I wrote my testcode originally with very idiosyncratic variable names, and hadn't actually recompiled the code after I changed them for my post. This should actually work: structc.c: ------- #include <stdio.h> struct passingstruct { unsigned int a; unsigned int b; int c; }; void printatest (struct passingstruct value) { printf ("hello!\n"); printf ("%u %u %d\n", value.a, value.b, value.c); } ---- structd.d: ------ import std.stdio; struct passingstruct { uint a; uint b; int c; void printme () { writefln ("%d %d", a, b); } } int main (char[][] args) { passingstruct test = passingstruct( 300, 200, 0); writefln ("%u %u %d", test.a, test.b, test.c); printatest (test); return 0; } extern (C) { void printatest (passingstruct value); }
Apr 13 2013
http://d.puremagic.com/issues/show_bug.cgi?id=5570
Apr 14 2013