Graeme wrote: > Changing those two procedures to the following code shown below works fine. > ... > Also, your initial code for the second array should actually be inside the > DoItOut() procedure
Yes, I know it works if you change the "array of char" parameters to simply reflect the dynamic array type. I was doing it that way to illustrate the crash. Also, I know the "fillchar" on the second example is ineffectual, however, it's how you get it to crash. If you don't have something in the array before the second call, it doesn't crash. This is because in the call to fpc_dynarray_decr_ref it appears to be dereferencing a pointer that's already dereferenced, but if the array is empty to begin with it just so happens that the data there is full of #0 characters so it doesn't make it past the "nil" check. Jonas, thank you for the explanation about "out" vs. "var" when it comes to reference counted data. I'd not stopped to think about it, but that makes perfect sense. And, looking at the assembly code, you are correct, it is the attempt to get the reference count that causes it to crash. > The compiler should simply refuse to compile your program. As for that, I understand what you're saying, but I'm not sure I feel the same way. Or, better said, I am glad that it *does* work (as long as I use "var" instead of "out.") The reason being is I have quite an extensive unit which does manipulations on arrays of characters: however, I have some variables in records which are declared as static, fixed arrays and others declared like "type myType = array of char." As it currently works, I am able to pass both kinds as open array of char arguments and it all just works (well, now that I've gone through and replaced the "out" with "var" :)). When I say it just works, I mean the the correct pointer and high bound is passed in both cases. If the compiler were to forbid me to do that I'd be unable to use a single set of these routines for both cases. >From what I could see in the assembler code, when the parameter was declared as "out whatever : array of char" and I passed in a typed dynamic array variable, in the call to fpc_dynarray_decr_ref called before my procedure was called it appears it was trying to dereference the memory where the array data was stored, but that register already contains the pointer to the data, so there's no need to dereference it. However, once I realized that I really wanted "var" rather than "out", the call to fpc_dynarray_decr_ref is, of course, no longer being made, and it just works. Thanks again for the input. And, as a side note, as I tell all my developer friends, the FPC community of developers and users is just top-notch. Thanks so much for the effort and high quality that is the Free Pascal compiler, and for always being so informative, helpful, and accessible when it comes to the mailing list discussions. You guys really are a class act. At my company we're just finishing converting a couple of million lines of code from Modula-2 to Object Pascal using the Free Pascal compiler and it's incredible how smooth the transition has been. And when I have run into roadblocks or questions, the mailing lists have been so helpful. Anyway, I just wanted to say "thanks." -Seth -- This email is fiction. Any resemblance to actual events or persons living or dead is purely coincidental. Seth Grover sethdgrover[at]gmail[dot]com On Tue, Apr 27, 2010 at 3:21 PM, Seth Grover <[email protected]> wrote: > Observe the following test program (http://pastebin.org/186091 for > those who prefer): > > ============================================================ > program dynarrayout; > > {$mode objfpc}{$H+} > > uses > SysUtils; > > procedure DoItVar(var yourArray : array of char); > begin > end; > > procedure DoItOut(out yourArray : array of char); > begin > end; > > type > DynCharArray = array of char; > > var > myArray : DynCharArray; > myArray2 : DynCharArray; > begin > SetLength(myArray, 64); > try > FillChar(myArray[0], Length(myArray), '!'); > DoItVar(myArray); > writeln('DoItVar is ok'); > except > on E : Exception do begin > writeln('Exception calling DoItVar: ', E.Message); > end; > end; > SetLength(myArray, 0); > > SetLength(myArray2, 64); > try > FillChar(myArray2[0], Length(myArray2), '~'); > DoItOut(myArray2); > writeln('DoItOut is ok'); > except > on E : Exception do begin > writeln('Exception calling DoItOut: ', E.Message); > end; > end; > SetLength(myArray2, 64); > end. > ============================================================ > > So basically I have a type defined as a dynamic array of characters, > which I fill with some data. If I have a function which takes a > parameter which is a "var array of char" into which I pass a variable > of my dynamic array type it works fine. However, if I have a function > where the parameter is an "out array of char", I get a crash when I > try to pass in my variable. > > Is this behavior correct? Can someone explain this to me? I thought > that the only difference between "var" and "out" was whether or not > the compiler warned you about uninitialized data. > > Thanks, > > -SG > > -- > This email is fiction. Any resemblance to actual events > or persons living or dead is purely coincidental. > > Seth Grover > sethdgrover[at]gmail[dot]com > _______________________________________________ fpc-devel maillist - [email protected] http://lists.freepascal.org/mailman/listinfo/fpc-devel
