understanding management operators lazarus / 62-General ---------------------------------------------------------------------- soerensen3 · 2018-07-26 20:45 I'm trying to understand management operators but there is something that makes me wonder. I just implemented a simple test record to implement all four management operators to understand when which operator gets called. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program project1; {$MODE delphi}uses Classes; type   TTest = record    index: Integer;    class operator Initialize(var aRec:TTest);    class operator Finalize(var aRec:TTest);    class operator AddRef(var aRec:TTest);    class operator Copy(constref aSource:TTest; var aDest:TTest);  end; class operator TTest.Initialize(var aRec: TTest);begin  WriteLn( 'Initialize' );end; class operator TTest.Finalize(var aRec: TTest);begin  WriteLn( 'Finalize' );end; class operator TTest.AddRef(var aRec: TTest);begin  WriteLn( 'AddRef' );end; class operator TTest.Copy(constref aSource: TTest; var aDest: TTest);begin  WriteLn( 'Copy' );end; type  PTest = ^TTest; var  a: TTest;  b: PTest; begin  WriteLn( '> a:= default( TTest );' );  a:= default( TTest );  WriteLn( '> New( b )' );  New( b );  WriteLn( '> b^:= a;' );  b^:= a;  WriteLn( '> end.' );end. The result is strange. I would assume that when the pointer to TTest is "freed" the finalize of the record is called. But I have to Dispose( b );  to make it do that. I understand that if I assign memory it is not automatically freed but there is no way of telling when a pointer is used when it is freed. So it is not possible to efficiently use pointers of records for managed types? Is that correct? QuoteInitialize > a:= default( TTest ); Copy > New( b ) Initialize > b^:= a; Copy > end. Finalize ---------------------------------------------------------------------- PascalDragon · 2018-07-26 21:40 From my understanding it shouldn't matter whether it's a pointer or not, Finalize() should be called nevertheless. Might be a bug... ---------------------------------------------------------------------- hnb · 2018-07-26 23:28 This is not bug Sven. It works as expected/designed. ATM the only known bug related to management operators is : https://bugs.freepascal.org/view.php?id=33157 every call of "New" needs "Dispose", nothing new here (it behaves like any other managed record). The hardest part to understand is how AddRef and Copy operators works, maybe this may helps: https://github.com/newpascal/freepascal/blob/master/tests/test/tmopera tor8.pp https://github.com/maciej-izak/PascalSmartPointers The management operators functionality has not much sense without "default field" functionality and without my further work, which is discontinued in FPC and probably will be continued only with NewPascal (with eventually bug fixes for management operators including #33157). "default field" functionality can be tested in NewPascal - PascalSmartPointers repository works with NewPascal only. Management operators in this raw forms are not much end-user friendly (especially copy/addref operators). With management operators you can track how managed types works in FPC/NewPascal in details. ---------------------------------------------------------------------- PascalDragon · 2018-07-27 07:09 Quote from: hnb on July 27, 2018, 01:28:24 amThis is not bug Sven. It works as expected/designed. ATM the only known bug related to management operators is : https://bugs.freepascal.org/view.php?id=33157 every call of "New" needs "Dispose", nothing new here (it behaves like any other managed record). The hardest part to understand is how AddRef and Copy operators works, maybe this may helps: https://github.com/newpascal/freepascal/blob/master/tests/test/tmopera tor8.pp https://github.com/maciej-izak/PascalSmartPointers It's not about the missing Dispose(). The unclear part is what task the Copy-operator needs to fullfill. When record a is assigned to record b (no matter whether its a pointer to a record or a plain variable) does the operator need to finalize the destination record? Probably it simply needs to do what is necessary so that what the user wants to achieve with the managed record is indeed achieved... So it's indeed not a bug. *shrugs* Quote from: hnb on July 27, 2018, 01:28:24 amThe management operators functionality has not much sense without "default field" functionality and without my further work, which is discontinued in FPC and probably will be continued only with NewPascal (with eventually bug fixes for management operators including #33157). "default field" functionality can be tested in NewPascal - PascalSmartPointers repository works with NewPascal only. Management operators in this raw forms are not much end-user friendly (especially copy/addref operators). With management operators you can track how managed types works in FPC/NewPascal in details. Would you please stop saying that management operators only make sense with the default field? Because you being so focused on smart pointers blinds you for other purposes such managed records can be used for. After all C++'s copy- and default-constructors (which are the equivalent to the management operators) are useful without an overload of the dereferentiation-operator as well. In fact in our C++ code at work I only know of one instance where we overloaded that operator (namely for automatic reference counting, aka smart pointers), but many more instances where the copy- and default-constructors are overloaded. ---------------------------------------------------------------------- soerensen3 · 2018-07-27 08:21 Thanks for your responses. My point was not that it should call dispose automatically because than it would already be a smart pointer. If you think of the operators as events, than there is no event for a pointer to the rec going out of scope and (I don't have the time right now to test this) probably no event for only copying the pointer. So my conclusion was the record is only managed if you are not working with pointers (typed or not), where you have to call either New or GetMem and finally Dispose. I'm asking because for a linked list I don't see any other way of using a pointer for a next field. ---------------------------------------------------------------------- hnb · 2018-07-27 09:09 Quote from: PascalDragon on July 27, 2018, 09:09:51 amWould you please stop saying that management operators only make sense with the default field? Because you being so focused on smart pointers blinds you for other purposes such managed records can be used for. No Sven, I will saying this all the time, because this is part of true. Smart pointers is just part of my work, stop saying nonsense about my "blindness" because you're far away from true. There is also part "and without my further work" which is related to other things (not only related to smart pointers), which was also mentioned in my other messages. Anyway default field is still important part. Management operators are just base for other language features and the current state of management operators is just first step, in general management operators are not much usable yet. The work is discontinued in FPC and will be expanded in NewPascal on other fields. I had no chance to discuss this with core but there will be no occasion for this. *shrugs* You are too much focused on C++... I will say it again: management operators are not much usable without further extensions (I mean not only default field). Using it as-is is very frustrating and they were designed as part of other features not as main feature. So NewPascal is the last hope : ( . ---------------------------------------------------------------------- hnb · 2018-07-27 09:29 Quote from: soerensen3 on July 27, 2018, 10:21:10 amThanks for your responses. My point was not that it should call dispose automatically because than it would already be a smart pointer. If you think of the operators as events, than there is no event for a pointer to the rec going out of scope Pointer is not managed as-is/disposed automatically. For this you need additional smart pointer: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  a: TTest;  b: TDisposablePtr;begin...  b := New( PTest );...  Note1: TDisposablePtr is not yet available in my SmartPointers library. Note2: class operator Implicit is very important to play with management operators. Note3: this can be achieved only with NewPascal, because it has also few bug fixes for generics not provided with FPC. Note4: here TDisposablePtr is the other managed record with management operators and with "default field"