digitalmars.D.bugs - problem with delegates and arrays?
- Sean Kelly (23/23) Jun 17 2004 This code:
- Charlie (7/30) Jun 17 2004 I dont see any delgates in there ? I see the nested function ..
- Sean Kelly (63/66) Jun 17 2004 That's what I meant. I should really learn to not post until after I've...
- Sean Kelly (6/6) Jun 17 2004 I just realized that this second problem is intended behavior. I had mi...
- Kris (32/38) Jun 17 2004 classes, ie.
This code: void fn( out char[] buf ) { void fn2() { printf( "%i, %i: %.*s\n", buf.length, buf.size, buf ); } fn2(); printf( "%i, %i: %.*s\n", buf.length, buf.size, buf ); } int main() { char[] buf; printf( "%i, %i: %.*s\n", buf.length, buf.size, buf ); fn( buf ); return 0; } prints: 0, 8: 0, 8: So as far as I can tell, the stack pointer is messed up for dynamic arrays within delegates.
Jun 17 2004
I dont see any delgates in there ? I see the nested function .. This problem goes away when you remove the 'out' and replace with 'in', however 'inout' seems also to fail. Assiging buf a value fails also. compiled with -inline it works as expected, weird. Charlie In article <casd8k$18ac$1 digitaldaemon.com>, Sean Kelly says...This code: void fn( out char[] buf ) { void fn2() { printf( "%i, %i: %.*s\n", buf.length, buf.size, buf ); } fn2(); printf( "%i, %i: %.*s\n", buf.length, buf.size, buf ); } int main() { char[] buf; printf( "%i, %i: %.*s\n", buf.length, buf.size, buf ); fn( buf ); return 0; } prints: 0, 8: 0, 8: So as far as I can tell, the stack pointer is messed up for dynamic arrays within delegates.
Jun 17 2004
In article <casnln$1oe1$1 digitaldaemon.com>, Charlie says...I dont see any delgates in there ? I see the nested function ..That's what I meant. I should really learn to not post until after I've had some coffee :)This problem goes away when you remove the 'out' and replace with 'in', however 'inout' seems also to fail.Yup, I noticed this too, so perhaps the problem is with parameter specifiers. However I think there's a related bug that's affecting me too. I'm still working on shrinking this repro, but this is the best I've done so far: interface I { void fn( char[] buf ); } template T() { template doFn( CharT ) { void fn( CharT[] val ) { size_t len = 0; CharT ch; void append( CharT ch ) { printf( "%i, %i: %.*s\n", val.length, val.size, val ); if( ++len > val.length ) val.length = len * 2; val[len-1] = ch; } ch = '1'; append( ch ); ch = '2'; append( ch ); ch = '3'; append( ch ); ch = '4'; append( ch ); val.length = len; return this; } } mixin doFn!(char) doFnC; alias doFnC.fn fn; } class C : I { mixin T; } int main() { char[] buf; I i = new C(); i.fn( buf ); printf( "%i, %i: %.*s\n", buf.length, buf.size, buf ); return 0; } prints: 0, 8: 2, 8: 1 2, 8: 12 6, 8: 123 0, 8: Basically, in this code I can't use the inner function "append" at all. If I add the "out" qualifier then the dynarray is garbage and I get an access violation, and if I leave it out then the changes don't persist once I leave the function. With the above code, if every call to "append" is replaced with the code inside "append" then everything works as expected.
Jun 17 2004
I just realized that this second problem is intended behavior. I had mistakenly thought that dynamic arrays would be governed by the same rules as classes, ie. that they are reference counted and are always implicitly passed as inout. It looks like the out qualifier must be used in order to have changes to dynarrays persist. So the only bug I see is the corrupt stack pointer when using inner classes.
Jun 17 2004
"Sean Kelly" wrote ...I just realized that this second problem is intended behavior. I hadmistakenlythought that dynamic arrays would be governed by the same rules asclasses, ie.that they are reference counted and are always implicitly passed as inout.Itlooks like the out qualifier must be used in order to have changes todynarrayspersist. So the only bug I see is the corrupt stack pointer when usinginnerclasses.A while back I ran into this one also, Sean. I forget the title of the bug-report, but the resultant code looks like this (note the char[] tmp for getting around funky nesting stack alignment issues; you can't directly assign the argument 'x' from within the nested function): /***************************************** Extract a char array from the current read-position *****************************************/ IReader get (out char[] x) { char[] tmp; int size; // callback to assign the prescribed content int read (void[] content) { tmp = cast(char[]) content; if (! mapped) tmp = tmp.dup; return tmp.length; } // how many bytes in this array? get (size); buffer.preserve (size, &read); // set output argument and go home x = tmp; return this; }
Jun 17 2004