Re: [fpc-pascal] Re: ++ and -- ( and +=, -=, ...)
Somehow relevant, has someone thought of turning Inc()/Dec() into functions that return the modified value -like the Interlocked ones? I think this would cover some of the cases discussed in a more "pascalish" notation.Also, Include()/Exclude() could similarly be turned into functions. -- Constantine Yannakopoulos ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] How To write an enumerator for trees
On Fri, Mar 22, 2013 at 12:39 AM, S. Fisher wrote: > --- On Thu, 3/21/13, kyan wrote: > Are you the man who created Kyan Pascal? I used that many > years ago. I'd never heard of it till now. I wish. I'm nowhere nearly that good. :) ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] How To write an enumerator for trees
On Thu, Mar 21, 2013 at 10:32 AM, Xiangrong Fang wrote: > I have read this. My question is not about how to write enumerator, but how > to do this for TREEs Usually linearizing recursion is done with a stack. Here's a sample implementation that will give you an in-order tree traversal (Left - Parent - Right), that for a binary search tree will produce a sorted enumeration: constructor TTreeEnumerator.Create(ATree: TTree); begin FStack := TStack.Create; FStack.Push(FTree.FRoot); end; function TTreeEnumerator.DoMoveNext: Boolean; var Node: PNode; begin if FStack.Empty then Exit(False); while not FStack.Empty do begin Node := FStack.Pop; if not Assigned(Node) then begin FCurrent := FStack.Pop; Exit(True); end else begin if Assigned(Node.Right) then FStack.Push(Node.Right); FStack.Push(Node); FStack.Push(nil); if (Node.Left <> nil) then FStack.Push(Node.Left); end; end; end; To reverse the sorting just swap Left and Right in the code of DoMoveNext. HTH Constantine ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] TurboPower FlashFiler for Free Pascal
On Tue, Oct 23, 2012 at 4:34 PM, wrote: > If I understand Graeme correctly, he wants it compiled-in (i.e. without > dll). SQLite is a separate DLL. SqLite source can be downloaded and compiled with a C compiler (e.g. CBuilder) and its .lib file linked directly in a Delphi application using the {$L} or {$LINK} directive. Is FPC capable of linking a .lib file? ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Header translation, argument list, array of const?
On Sat, Jun 30, 2012 at 12:21 AM, Bernd wrote: > Hello, I need to call the following function: > > > /** > * Notifies Purple that a buddy's status has been activated. > * > * This is meant to be called from protocol plugins. > * > * @param account The account the user is on. > * @param name The name of the buddy. > * @param status_id The status ID. > * @param ... A NULL-terminated list of attribute IDs and values, > * beginning with the value for @a attr_id. > */ > void purple_prpl_got_user_status(PurpleAccount *account, const char *name, > const char > *status_id, ...) G_GNUC_NULL_TERMINATED; > > > I have translated it as follows: > > procedure purple_prpl_got_user_status(account: PPurpleAccount; > name_, status_id: PChar; par3: array of const); cdecl; external LIBPURPLE; That would be: procedure purple_prpl_got_user_status(account: PPurpleAccount; name_, status_id: PChar); varargs; cdecl; external LIBPURPLE; "varargs" is a compiler directive that reflects the ellipsis "..." in C. It is only valid in external function declarations for static linking (as in your case) or function prototypes for dynamic linking using LoadLibrary()/GetProcAddress(). It is always combined with cdecl (read on) and you cannot implement a varargs cdecl function (you get a compiler error if you try), only declare a prototype and link to an external one written in C. I am not 100% sure FPC supports the varargs directive but I've found at least one varargs cdecl function (gtk_tree_path_new_from_indices in gtk2extrah.inc), so it probably does. > How is this such a list of arguments actually implemented? is it on > the stack? What structure does it have? Can I somehow manually put > stuff onto the stack to make it think it is an empty list? maybe pass > another integer and pass 0 instead of this list? I am no C programmer but as I understand it the caller can pass as many variable parameters of any type (actually it has to pass what the function expects it to). The parameters are pushed into the stack after fixed parameters and the callee (function) will retrieve them out of the stack with pointer arithmetic using the address past the end of the last fixed parameter (in your case status_id) as a starting point and increment the running pointer according to every expected variable parameter's type size. So the number and type of the variable parameters must be known and respected by both caller and function and is usually deduced by the values of the fixed parameters. A well known such function with variable parameters is printf() where the type and number of variable parameters is deduced by the placeholders in the format string passed as the fixed parameter. In your case I think that the value of the status_id parameter dictates the number and type of the extra parameters. You'll have to read the documentation of the function. Stack cleanup is possible although the parameter stack has an unknown size at compile time because of the cdecl calling convention where the caller must allocate AND cleanup the stack and the caller knows the number and types of the variable params at compile-time, the function doesn't. In other calling conventions where the caller allocates the stack but the function has to clean it up (e.g. pascal/stdcall) the ellipsis/varargs cannot work. A pascal open array of const which is the closest concept to a C ellipsis may have similar semantics but its binary representation on the parameter stack is completely different. First of all, since it has to work in all calling conventions and not just cdecl the high bound of passed array elements is pushed in the stack after a pointer to an array of TVarRec structures that each contains a type attribute and either a value or a pointer to the value of the parameter. So the open array doesn't need to be the last parameter like the C ellipsis and there can be more than one in a routine signature. So your declaration of purple_prpl_got_user_status procedure purple_prpl_got_user_status(account: PPurpleAccount; name_, status_id: PChar; par3: array of const); is equivalent to: procedure purple_prpl_got_user_status(account: PPurpleAccount; name_, status_id: PChar; par3: PVarRecArray; par3HighBound: Integer); So the caller pushes only a pointer to a TVarRec array and an integer while the function expects a continuous "stream" of parameters. If you pass [] the compiler generates code to push a nil pointer (zero PtrInt) and a high bound of -1. If the C function can handle these values on the stack it *sort of* works by accident, but it will probably fail if it tries to read past the -1 high bound for a specific value of status_id that requires more variable parameters. For details on open array parameters read this article: http://rvelthuis.de/articles/articles-openarr.html (Disclaimer: the description of open arrays apply to Delphi but my guess is that the im
Re: [fpc-pascal] Unhandled exception from library crashes host exe
On Thu, Jun 28, 2012 at 12:45 PM, Jonas Maebe wrote: > The safecall calling convention is only supported on a few platforms. > Originally it was only supported on Windows. Nowadays it's also supported on > a few extra platforms because it was required for XPCOM (someone wanted to > use XPCOM on certain platforms, and only added suppport for safecall on > those particular platforms), but it's definitely not yet supported > everywhere. I'm also not aware of anyone planning on adding support for > safecall on other platforms. I want it for Win32/64, WinCE/arm and Linux. How can I find whether it is implemented on these platforms without having to actually test it? I went so far as to see that fpc_safecallcheck that calls the SafeCallErrorProc callback exists in system.inc but could not find where it is called. Thanks in advance. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Unhandled exception from library crashes host exe
On Wed, Jun 27, 2012 at 8:15 PM, Sven Barth wrote: > Summa summarum: don't let exceptions travel past the DLL boundary. One might > be able to fix it on Windows, but *nix maybe not so much... Thank you for your reply Sven. It seem that the way to go -I don't have much knowledge on SEH so I'd rather not mess with such low level system code- is to try to turn my API to safecall and install a SafeCallErrorProc handler that will try to recreate and raise the safecall exception from the callee module to the caller one, which will eventually bubble up to the exe and the main message loop. From what I've seen the safecall exception is not based on any OS functionality but it is implemented by "compiler magic" therefore I expect it to work (at least for application-defined exceptions) in all OSes. As I see it, if all interface methods exposed by a dll are safecall no exception will cross dll boundaries since it will be trapped by the compiler-generated safecall "try-finally" code and jump to TObject.SafeCallException() which must be overridden to pass the exception data to some sort of global storage. Then I will have to install a SafeCallErrorProc callback that will poll the global storage and reraise an exception based on the data placed there by TObject.SafeCallException(). This way no Exception descendant will ever pass any dll boundary and chaining is possible (exe calls dll1 which calls dll2 which raises an exception, dll2 traps it, places it in the global storage, dll1 reraises it in its SafeCallErrorProc and traps it and places it again in the global storage and exe reraises it in its SafeCallErrorProc). The only difficulties are that the global storage must be singleton to all modules (shared memory f.ex.) and must have separate storage per thread. Just like COM/OLE does it with the IErrorInfo object. It is a good thing that my API is based on interfaces and not on regular exported functions -except for a "factory" function that never raises an exception and all objects whose methods cross dll boundaries have 2 or 3 common ancestors. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Unhandled exception from library crashes host exe
Thank you all for your replies. > Regular exceptions, those raised with the "raise" keyword are always trapped > by try..except blocks but you have to make sure that EVERY method in the DLL > that is called by the host exe has such a construct so as not to let the > exception escape. As I already mentioned this is not an option for me within my given time frame. I am talking about an application with more than 20 dlls, hundreds of thousands of lines of code and a heavy API between exe and dlls based on interfaces. Even if I decided to bite the bullet and -for instance- turn every interface method to "safecall" and add "safecall" functionality in every object -I suppose that this would do the trick- this would take a considerable amount of time, unacceptable for production code that gets a release with new features every couple of weeks. > However, there are exceptions that come from the FPU and that arise when > doing floating point maths. Those, in a DLL, are not trapped by the > try..except blocks and are passed back to the host exe, effectively crashing > them. > If you want to trap them, you have to add a special unit in your DLL > project, as explained in this issue: > > http://bugs.freepascal.org/view.php?id=12974 > > Look for the last comment, it works fine here I've read it and it seems to work for AVs and FPU exceptions only, not for application-defined exceptions, is this correct? If so then it will not be enough for me I'm afraid. > That will not help. The problem described there appears only on Win64. > Not on Windows 32 or linux. Actually I am compiling with the 32bit version of FPC/Lazarus producing 32bit images but running in a Windows 7 64-bit OS. I am not sure if the problem appears in Win64 even with 32bit code. I can only confirm that the situation is exactly the same in WinCE. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Unhandled exception from library crashes host exe
I am sure that this has been asked before but I couldn't find an answer. I am in the process of porting a large application consisting of an exe and many dlls from Delphi7 to FPC 2.7.1/Lazarus for Windows/WinCE with hopes of being able to finally port it to Linux. I have managed to overcome all obstacles but this seems like a brick wall: An exception raised from a dll that is not handled by the dll's code will crash the exe, bypassing any try/finally/except handlers around the call into the dll that raised it. This is of course a complete showstopper because the API and code of the dlls is way too massive to re-engineer so that it does not let exceptions bubble up to the exe. In Delphi without packages the aforementioned situation can be handled reasonably well because despite the fact that operators "is" and "as" won't work on the dll's Exception object (its class pointer points inside the dll's Exception class and not the exe's Exception class) at least the exception handlers work so one can display an error message and keep the main application loop running. It is solved perfectly if one builds all executables with runtime packages so that there is only one Exception class for the exe and all dlls. But in FPC there are no "runtime packages" in the Delphi sense, therefore there doesn't seem to be a solution to this. Can someone suggest a solution, even if I have to manually apply a patch to FPC and build it myself? Because if there isn't one I will have to scrap the whole project. Thank you in advance. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Adding method dynamically to a class
I suggest that you implement this using interfaces. You place the interface declaration in a common file, use the interfaces from the main exe but implement them in separate dlls. This gives you all the flexibility you want, e.g. group your methods into bundles and place them on different interfaces. You will only need a class identifying system (i.e. a "class id" string) that will be known to the exe and implementing dlls and a "factory" exported function in each dll that creates the implementing object of a known "class id". You can have many alternate implementations of an interface with different class ids and you can even replace an implementing dll with another version of it with bug fixes or even different functionality. In my mind it is always ==> Interfaces. HTH. On Wed, Jun 20, 2012 at 11:14 AM, ik wrote: > The idea of implementing it like so, came to me after few years now of > having the need to recreate the whole logic based of the code for every new > demand from the client (both as human, and as software). The main code > almost never changes, but so many additions, that I'm starting to use the > dynamic execution of methods, and now I realize, that if I'll extract it to > a shard library, it will be much easier to change, add etc... only the > actual need, and not to touch other stuff, and that requires me to design an > engine instead. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Strings and objects crossing dll boundaries
Hello all, A couple of questions regarding handling of strings, dynamic arrays and objects -especially exceptions- when writing programs that use shared libraries (.dll, .so). In Delphi we have the option of either using packages to ensure that there is only one instance of the memory allocator or use ShareMem.pas that installs a memory allocator that can handle memory allocations across libraries. Given that in FPC/Lazarus there are no "packages" in the Delphi sense what is the equivalent of ShareMem.pas? Is it cmem.pp? Regarding objects, in Delphi an object cannot safely cross dll boundaries because separate class record(s) for it exist in each executable file. OK, actually it can if one is certain that the class records compiled in each executable are identical. But if an exception crosses dll boundaries then you are in trouble, because the operator "is" does not work due to the class pointer that points to another Exception class record than the one known by the handling executable. The best way to solve this is to put the class Exception at least inside a package that all executables use so at least "is" will work for Exception. Is there a way to handle this problem in FPC that does not have packages? TIA Constantine. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Unit initialization in dll initialization for arm/WinCE
Thank you for your reply Sven. > It might't be that Windows (or CE only) initalizes a library only if you use > GetProcAddress at least once... I have not tested that, but it might be an > idea. If that is the case we can not influence that. No need to, it really doesn't matter since one has to do a GetProcAddress() in order to be able to call anything inside a dll. Maybe it is an optimisation that has to do with resource dlls. > If you want you can create a bug report. WinCE might likely be solved then, > but I can't comment on Linux or other *nix systems. It's OK, I've wrapped GetModuleName() in a function of my own that works as expected in Delphi, Win32, Win64 and WinCE and will stick to that. Will report when I find some time. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Unit initialization in dll initialization for arm/WinCE
OK, I apologize. It seems that the problem lies elsewhere. The fact that library initialization seems to be deferred until you do a GetProcAddress() confused me. The problem is that function GetModuleName() is stubbed out in WinCE (and Linux): unit SysUtils.inc; function GetModuleName(Module: HMODULE): string; begin {$ifdef MSWINDOWS} SetLength(Result,MAX_PATH); SetLength(Result,GetModuleFileName(Module, Pchar(Result),Length(Result))); {$ELSE} Result:=''; {$ENDIF} end; The function GetModuleFileName() exists (although it is unicode) in WinCE: http://msdn.microsoft.com/en-us/library/ms908441.aspx And from what I've found in the web a Linux implementation is possible using dladdr(). On Mon, Jun 11, 2012 at 1:53 PM, Sven Barth wrote: > Am 11.06.2012 12:25, schrieb kyan: > >> Does unit initialization in libraries (.dll files) work in arm/WinCE? > > > From the startup code of arm-wince I don't see why it should not work... > > >> Somehow it seems that even code placed in the library initialization >> begin end block isn't executed either. > > > How did you test this? > > >> I found some bug reports (e.g. >> 0019404) suggesting that this didn't work for arm/Linux but it has >> been added to the trunk. But not for arm/WinCE? > > > Linux and Windows have different schemes for library initialization, so even > if it was the case that arm-wince did not work it would not help to apply > the fix for arm-linux there as well. > > Regards, > Sven > ___ > fpc-pascal maillist - fpc-pascal@lists.freepascal.org > http://lists.freepascal.org/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Unit initialization in dll initialization for arm/WinCE
Hello all, Does unit initialization in libraries (.dll files) work in arm/WinCE? Somehow it seems that even code placed in the library initialization begin end block isn't executed either. I found some bug reports (e.g. 0019404) suggesting that this didn't work for arm/Linux but it has been added to the trunk. But not for arm/WinCE? If this is the case, is there a feasible workaround to call unit initialization sections manually? I am not statically linking the libraries by means of "external" clauses but I am using LoadLibrary() and GetProcAddress() to communicate with the dll from the exe, so I could create an exported function in the dll and call it manually from the exe after loading if I could somehow iterate in it the unit initialization sections and call them. Thank you in advance. Constantine. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Default value for an open array
> However, given a declaration of that form, is it possible to define a > default parameter of [] so that OutputWriteF('Test, no params\n') is > valid? Not for open arrays, but you can write an overloaded version without the open array argument that calls the version with the open array parameter passing an empty array, or an array initialised with whatever "default" values you want: interface procedure OutputWriteF(const str: widestring); overload; procedure OutputWriteF(const str: widestring; values: array of const); overload; implementation procedure OutputWriteF(const str: widestring); begin OutputWriteF(str, [clBlack, clDefault]); end; procedure OutputWriteF(const str: widestring; values: array of const); begin ... end; HTH Constantine. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Streaming of Generics
> Ideally, I'd only like to write the streaming mechanism for each set > of types (normal, anisstring, dynamic array, objects, interfaced > objects) once, and use it for every set of items. However, there's no > reasonable way to detect the type and do an execution for it. Ideally You can use the "magic" function TypeInfo() to detect the type of a generic parameter inside a method of a generic class. It returns a PTypeInfo pointer so you can use PTypeInfo(TypeInfo(T))^ record to determine the data type (Kind) -and other attributes- of the generic type. For the lack of generic procedures, you can substitute a generic procedure with a generic class method: type generic TStreamer = class public procedure StreamType( Stream : TStream; Data : T ); end; procedure TStreamer.StreamType( Stream : TStream; Data : T ); begin case PTypeInfo(TypeInfo(Data))^.Kind of tkString: ... tkInteger: .. end; end; HTH Constantine. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Reason of procedure overload RTLeventWaitFor(state, timeout) return.
Hello all, I am trying to port a small library previously written for Delphi and Kylix to FPC. This library contains an "event" object that has similar functionality to a windows kernel event. This object is supposed to have a method that lets you wait for the event object with a timeout and return whether the event was signaled of the timeout expired. After some searching I concluded that for a platform-independant implementation I should use the RTLeventXXX regular procedures/functions declared in threadh.inc because the basiceventXXX ones are stated as obsolete in the documentation. I noticed that the RTLeventWaitFor(state, timeout) overload does not return anything to tell the caller why it returned (signal or timeout) as Windows WaitForSingleObject() does. Is there a way to get the result of the last timed wait for the current thread? If not is there another way to implement a platform-independant event, maybe using some other set of functions? TIA Constantine. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Internal Error 2010021405 when compiling in Linux
On Wed, May 2, 2012 at 4:34 PM, Sven Barth wrote: > Your code triggers a different bug in the compiler than the mentioned report > though the presented error is the same. Please open a new bug report with a > example that should compile. Done, #0021921. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Internal Error 2010021405 when compiling in Linux
Hello all, I am trying to compile a program that contains the following code consturct: type THashEntry = record Key: string; Value: T; class function Create(const AKey: string; const AValue: T): THashEntry; static; inline; end; in Lazarus with FPC version 2.7.1 built from the trunk svn repos (http://svn.freepascal.org/svn/fpc/trunk/). It compiles in Windows but fails in (Fedora) Linux with the message: "Fatal: Internal error 2010021405". It is easily reproduced if you copy-paste the type declaration in a new project with $mode Delphi. This matches the bug #19500 which is marked as resolved by Sven Barth but it seems somehow not to have been fixed in Linux; I don't know if this is possible. I compared the sources of FPC for both Windows and Linux using Beyond Compare and there is no difference. What am I doing wrong? TIA Constantine. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: Class const of array of record.
On Fri, Feb 24, 2012 at 6:29 PM, Everton Vieira wrote: > Doesn't work this code doesn't compile: Sorry, I forgot to mention that advanced record syntax works in Delphi mode only. To compile it you must change {$mode objfpc} to {$mode Delphi}. See also: http://wiki.freepascal.org/FPC_New_Features_2.6.0#Advanced_record_syntax ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: Class const of array of record.
>> Is there any how to do it? You can use advanced record syntax and do something like this: type TRec = record Numero: Integer; Nome: String; class function Create(ANumero: Integer; const ANome: string): TRec; static; inline; end; ... class function TRec.Create(ANumero: Integer; const ANome: string): TRec; begin with Result do begin Numero := ANumero; Nome := ANome; end; end; ... procedure TForm1.Button1Click(Sender: TObject); begin ShowTRec(TRec.Create(1, 'Pascal')); end; PS: In Delphi advanced records can have constructors but not yet in FPC. A static class function can easily replace them. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Generic type parameter variable initialization
> Saying a FPC compiler developer to look at the Delphi implementation is > problematic, because than we could get accused of copying code (which is why > I use the Delphi XE starter version which does not contain the source code > of the RTL and VCL). I am sorry, I wasn't aware of that. But by means of testing I found that Finalize() works correctly for Variants in Lazarus as well. I don't know about the internals much but I suppose the place to look in FPC is procedure fpc_finalize() in objpas.inc which does handle tkVariant as well. > While this does indeed look nicely it's still not Delphi compatible ;) I think it is, it works in my Delphi XE exactly the way it does in Lazarus. It is just not defined in Delphi's RTL. I meant it as a temp solution until you implement Default() or something equivalent. Anyway, let me not waste any more of your time. :) Regards. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Generic type parameter variable initialization
On Thu, Jan 5, 2012 at 4:03 PM, Florian Klämpfl wrote: > Am 05.01.2012 14:19, schrieb Sven Barth: > Has the workaround really the same effect? I really wonder why there is > a need for default then ... Yes, works for Variants as well. Look at the implementation of System._FinalizeArray() in Delphi; it handles tkVariant type kind. Come to think of it, it can be elegantly wrapped up in the following generic class: type TDefault = class class function Value: T; inline; end; class function TDefault.Value: T; begin Finalize(Result); FillChar(Result, SizeOf(Result), 0); end; and used like this: type TSomeRec = record S: string; V: Variant; I: Integer; end; var S: string; I: Integer; V: Variant; X: IInterface; C: TObject; D: TDateTime; R: TSomeRec; P: Pointer; begin S := 'test'; I := 42; V := Date; D := Date; X := Self; C := Self; R.S := 'test1'; R.V := Date; R.I := 99; P := Self; S := TDefault.Value; I := TDefault.Value; V := TDefault.Value; D := TDefault.Value; X := TDefault.Value; C := TDefault.Value; R := TDefault.Value; P := TDefault.Value; end; ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
[fpc-pascal] Generic type parameter variable initialization
Hello everybody. I am new to FPC/Lazarus and I am trying to port some Delphi XE code that uses the units Generics.Defaults and Generics.Collections so I have to write these units for FPC because they do not exist and the code I am porting relies heavily on them. In this process I have come across various issues with Delphi/FPC generic compatibility but I have managed to overcome most of them. In a method of a generic class I need to initialize a variable of type "T" (the generic class type parameter) with the type T's "default" value, which is 0 for ordinal types, '' for strings, nil for pointers/classes/interfaces, Unassigned for Variants etc. In Delphi there is the "compiler magic" function Default() and you can write: procedure TMyClass.SomeMethod; var V: T; begin ... V := Default(T); ... end; This does not compile in FPC. Is there an alternative in FPC for the function Default()? I suppose one could do this: procedure TMyClass.SomeMethod; var V: T; begin ... Finalize(V); FillChar(V, SizeOf(V), 0); ... end; which is equivalent but it doesn't look too elegant. I am using FPC 2.7.1 for Win32/64. Thank you in advance, Constantine. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal