Comment #0 by mathias.baumann — 2011-03-04T10:07:48Z
Created attachment 929
test case demonstrating the problem
va_arg sets wrong length for ushort[]
the attached program outputs:
vararg_:
ubyte[].length = 3
ushort[].length = 140737237065760
short[].length = 139885158469104
uint[].length = 3
vararg:
ubyte[].length = 3
ushort[].length = 0
short[].length = 0
uint[].length = 3
I tested with D1, but the bug is possibly also existant in D2.
Comment #1 by clugdbug — 2011-03-15T02:04:42Z
When I compile the test code on D2 Windows (replacing tango.stdc.stdarg -> core.stdc.stdarg), I just get indication of memory corruption:
vararg_:
ubyte[].length = 18419671623532547
ushort[].length = 18419809062486019
short[].length = 18419860602093571
uint[].length = 18419912141701123
There's this code in the test case:
T[] usa;
va_arg(ap, _arguments[0],cast(void*) &usa);
Are you sure this is correct? Looks wrong to me, remember that static arrays are passed by value.
Comment #2 by mathias.baumann — 2011-03-15T03:41:30Z
I am not 100% sure, no. But I just replaced the array declerations with
ubyte uba[] = [ 32,33,34];
uint a[] = [1,2,3];
ushort c[] = [ cast(ushort)51, 52, 53 ];
short sc[] = [ cast(short)51, 52, 53 ];
and it resulted in the same problem.
I hope initializing them like this does qualify them as dynamic arrays. (?)
Comment #3 by andy — 2015-01-25T01:21:48Z
The example code (after changing tango.stdc.stdarg to core.stdc.stdarg) doesnt compile anymore (DMD v2.066.1)
I'd guess there are newer/better ways to handle this, so I'd recommend closing it.
I get:
/usr/include/dmd/druntime/import/core/stdc/stdarg.d(67): Error: cannot implicitly convert expression (cast(void*)(cast(uint)p + (tsize + 4u - 1u & 4294967292u))) of type void* to char*
main.d(15): Error: template instance core.stdc.stdarg.va_arg!() error instantiating
main.d(57): instantiated from here: varar_!ubyte
Comment #4 by schveiguy — 2015-01-26T12:46:16Z
I downloaded attachment, changed tango to core in both cases, compiles and runs with 2.066.1, and outputs:
vararg_:
ubyte[].length = 3
ushort[].length = 3
short[].length = 3
uint[].length = 3
vararg:
ubyte[].length = 3
ushort[].length = 3
short[].length = 3
uint[].length = 3
On Macos X (64-bit).