2016-04-12 17:15 GMT+02:00 Sven Barth <pascaldra...@googlemail.com>: > > Maybe "run" for my idea is a bad word. We don't need to run any section > before initialization section from system. What we need is the table/list > with "fixed" variables which needs to be initialized in system.pp > initialization (and finalized in finalization). I think that is doable. > > It doesn't matter. You need to run the initializer operators and these > might rely on functionality that is not initialized yet. So the safest > approach would definitely be to init these after all initialization > sections and to document this and the reasons behind it. This also > alleviates the need to use attributes for this (or a keyword or whatever). > Running the initializer operators after initialization is IMO bad idea... Very "pascal incompatible" and confusing even for me ;). I see many problems for that approach...
I think I have other solution (that also can help to solve old problems). What is needed is new section like "managementinitialization" and "managementfinalization" (to complement "initialization"/"finalization" with a little different logic). managementinitialization should contains only module related stuff (memory allocation etc.) mostly used/required by Initialize management operators without dependencies nor complex logic. How it supposed to work? Below is attached modified example presented by Thorsten Engler and modified example presented by Sven + my invention ;). Note: "$" prefix means -> invisible for programmer/created by compiler. === unit1 begin === unit unit1; interface uses InterfaceUsedUnit1, InterfaceUsedUnit2; //... Procedure $AddRef; Procedure $Release; type PSomeType = ^TSomeType; TSomeType = record ... with management operators end; function GetSomething: PSomeType; implementation uses ImplementationUsedUnit; var BufferForTSomeTypeManagementOperators: PByte; procedure $Init; begin InterfaceUsedUnit1.$AddRef; InterfaceUsedUnit2.$AddRef; ImplementationUsedUnit.$AddRef; //.. code from original initialization section goes here end; procedure $Finit; begin //.. code from original finalization section goes here ImplementationUsedUnit.$Release; InterfaceUsedUnit2.$Release; InterfaceUsedUnit1.$Release; end; var $RefCount: Integer; var gSomething: TSomeType; gSomething2: array[0..2] of TSomeType; function GetSomething: PSomeType; begin if not Assigned(gSomething.inst) then gSomething.inst := TObject.Create; Result := @gSomething; end; procedure $ManagementInit; begin $managementinitialization(); // execute our new section for operators purpose // genereted for all global variables with management operators InitializeArray(@gSomething, TypeInfo(TSomeType), 1); // call the Initialize operator InitializeArray(@gSomething2[0], TypeInfo(TSomeType), 3); end; procedure $ManagementFinit; begin // genereted for all global variables with management operators FinalizeArray(@gSomething, TypeInfo(TSomeType), 1); // call the Finalize operator FinalizeArray(@gSomething2[0], TypeInfo(TSomeType), 3); $managementfinalization(); // execute our new section for operators purpose end; procedure $AddRef; begin If LockedInc($RefCount) = 1 then begin $ManagementInit; $Init; end; end; procedure $Release; begin If LockedDec($RefCount) = 0 then begin $Finit; $ManagementFinit; end; end; managementinitialization // in the fact it is procedure with symbol $managementinitialization BufferForInitializeOperator := GetMem(100); initialization $AddRef; finalization $Release; managementfinalization // in the fact it is procedure with symbol $managementfinalization FreeMem(BufferForInitializeOperator); end. === unit1 end === simplified than unit1, but behind the scene is the same mechanism === unit2 begin === unit unit2; interface implementation uses unit1; // initialization Writeln(GetSomething^.inst.ToString); // no memory leak anymore even if inst is filled inside TSomeType.Initialize operator end. === unit2 end === -- Best regards, Maciej Izak
_______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel