Recent

Author Topic: Unexpected deprecated warnings at end of constructors  (Read 3463 times)

Чебурашка

  • Hero Member
  • *****
  • Posts: 593
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Unexpected deprecated warnings at end of constructors
« on: September 06, 2023, 12:00:24 pm »
I have these files

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.       Classes, SysUtils;
  9.  
  10. type
  11.  
  12.         { TMyClass }
  13.  
  14.   TMyClass = class(TObject)
  15.     private
  16.       FParam: Integer;
  17.     public
  18.       constructor Create(aParam: Integer); reintroduce; overload; deprecated;
  19.       constructor Create(); reintroduce; overload; deprecated;
  20.       destructor Destroy(); override; deprecated;
  21.      
  22.       property Param: Integer read FParam write FParam;
  23.   end;
  24.  
  25. implementation
  26.  
  27. { TMyClass }
  28.  
  29. constructor TMyClass.Create(aParam: Integer);
  30. begin
  31.   inherited Create();
  32.  
  33.   FParam:=aParam;
  34. end;
  35.  
  36. constructor TMyClass.Create();
  37. begin
  38.   Create(0);
  39. end;
  40.  
  41. destructor TMyClass.Destroy();
  42. begin
  43.   inherited Destroy();
  44. end;
  45.  
  46. end.  
  47.  

Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. uses SysUtils, Unit1;
  4.  
  5. var
  6.   x: TMyClass;
  7. begin
  8.   x := TMyClass.Create(4);
  9.  
  10.   Writeln(IntToStr(x.Param));
  11.  
  12.   x.Destroy();
  13. end.
  14.  

when I build I get this:

Code: Bash  [Select][+][-]
  1. [11:57:33] mep@mep-development:~/tmp/2023-09-06-testdepr$ lazbuild -B project1.lpi
  2. Hint: (lazarus) Build Project: nothing to do.
  3. Info: (lazarus) Execute Title="Compile Project, Target: project1"
  4. Info: (lazarus) Working Directory="/home/mep/tmp/2023-09-06-testdepr/"
  5. Info: (lazarus) Executable="/usr/bin/fpc"
  6. Info: (lazarus) Param[0]="-B"
  7. Info: (lazarus) Param[1]="-MObjFPC"
  8. Info: (lazarus) Param[2]="-Scghi"
  9. Info: (lazarus) Param[3]="-Cg"
  10. Info: (lazarus) Param[4]="-O1"
  11. Info: (lazarus) Param[5]="-g"
  12. Info: (lazarus) Param[6]="-gl"
  13. Info: (lazarus) Param[7]="-l"
  14. Info: (lazarus) Param[8]="-vewnhibq"
  15. Info: (lazarus) Param[9]="-Fi/home/mep/tmp/2023-09-06-testdepr/lib/x86_64-linux"
  16. Info: (lazarus) Param[10]="-Fu/home/mep/tmp/2023-09-06-testdepr/"
  17. Info: (lazarus) Param[11]="-FU/home/mep/tmp/2023-09-06-testdepr/lib/x86_64-linux/"
  18. Info: (lazarus) Param[12]="-FE/home/mep/tmp/2023-09-06-testdepr/"
  19. Info: (lazarus) Param[13]="-o/home/mep/tmp/2023-09-06-testdepr/project1"
  20. Info: (lazarus) Param[14]="project1.lpr"
  21. Hint: (11030) Start of reading config file /etc/fpc.cfg
  22. Hint: (11031) End of reading config file /etc/fpc.cfg
  23. Free Pascal Compiler version 3.2.0+dfsg-12 [2021/01/25] for x86_64
  24. Copyright (c) 1993-2020 by Florian Klaempfl and others
  25. (1002) Target OS: Linux for x86-64
  26. (3104) Compiling project1.lpr
  27. (3104) Compiling Unit1.pas
  28. /home/mep/tmp/2023-09-06-testdepr/Unit1.pas(34,1) Warning: (5043) Symbol "Destroy" is deprecated
  29. /home/mep/tmp/2023-09-06-testdepr/Unit1.pas(38,12) Warning: (5043) Symbol "Create" is deprecated
  30. /home/mep/tmp/2023-09-06-testdepr/Unit1.pas(39,1) Warning: (5043) Symbol "Destroy" is deprecated
  31. /home/mep/tmp/2023-09-06-testdepr/project1.lpr(8,26) Warning: (5043) Symbol "Create" is deprecated
  32. /home/mep/tmp/2023-09-06-testdepr/project1.lpr(12,14) Warning: (5043) Symbol "Destroy" is deprecated
  33. (9015) Linking /home/mep/tmp/2023-09-06-testdepr/project1
  34. (1008) 61 lines compiled, 0.3 sec
  35. (1021) 5 warning(s) issued
  36. (1022) 2 hint(s) issued
  37. [11:57:50] mep@mep-development:~/tmp/2023-09-06-testdepr$
  38.  

I understand all deprecated warnings but these:

Code: Bash  [Select][+][-]
  1. /home/mep/tmp/2023-09-06-testdepr/Unit1.pas(34,1) Warning: (5043) Symbol "Destroy" is deprecated
  2. /home/mep/tmp/2023-09-06-testdepr/Unit1.pas(39,1) Warning: (5043) Symbol "Destroy" is deprecated
  3.  

Any idea?

PS: I am not interested in replies like "why do you deprecate constructor/destructor", so if someone plans to answer like this, please avoid. There's a reason for this deprecation related to (future) clients of this class.
« Last Edit: September 06, 2023, 12:08:57 pm by Чебурашка »
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Zvoni

  • Hero Member
  • *****
  • Posts: 3370
Re: Unexpected deprecated warnings at end of constructors
« Reply #1 on: September 06, 2023, 01:10:44 pm »
?
I was of the mind, that you should NEVER call "Destroy", but "Free" instead

EDIT: Huh?
Just tested your sample-code
The Warning for "Destroy" being deprecated is at the "End;" of the Create-Method?!?!?
That's not making a lick of sense to me
« Last Edit: September 06, 2023, 01:14:35 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

alpine

  • Hero Member
  • *****
  • Posts: 1412
Re: Unexpected deprecated warnings at end of constructors
« Reply #2 on: September 06, 2023, 01:22:09 pm »
What about auto destroying from a failed constructor?
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Чебурашка

  • Hero Member
  • *****
  • Posts: 593
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Unexpected deprecated warnings at end of constructors
« Reply #3 on: September 06, 2023, 01:25:27 pm »
EDIT: Huh?
Just tested your sample-code
The Warning for "Destroy" being deprecated is at the "End;" of the Create-Method?!?!?
That's not making a lick of sense to me

This is what I was asking for.
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Чебурашка

  • Hero Member
  • *****
  • Posts: 593
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Unexpected deprecated warnings at end of constructors
« Reply #4 on: September 06, 2023, 01:26:25 pm »
What about auto destroying from a failed constructor?

Could you please explain better?
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Zvoni

  • Hero Member
  • *****
  • Posts: 3370
Re: Unexpected deprecated warnings at end of constructors
« Reply #5 on: September 06, 2023, 01:30:01 pm »
What about auto destroying from a failed constructor?
If a Constructor fails, would you even have something to destroy?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Чебурашка

  • Hero Member
  • *****
  • Posts: 593
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Unexpected deprecated warnings at end of constructors
« Reply #6 on: September 06, 2023, 01:31:23 pm »
I was of the mind, that you should NEVER call "Destroy", but "Free" instead

In normal code I do like that.
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

alpine

  • Hero Member
  • *****
  • Posts: 1412
Re: Unexpected deprecated warnings at end of constructors
« Reply #7 on: September 06, 2023, 02:02:21 pm »
What about auto destroying from a failed constructor?

Could you please explain better?

Destructor will be called automatically on exception raised in constructor. See the attached picture.

What about auto destroying from a failed constructor?
If a Constructor fails, would you even have something to destroy?
May be partially constructed at the time of the exception. You may need to free allocated memory, etc.

"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Zvoni

  • Hero Member
  • *****
  • Posts: 3370
Re: Unexpected deprecated warnings at end of constructors
« Reply #8 on: September 06, 2023, 02:10:27 pm »
EDIT: Huh?
Just tested your sample-code
The Warning for "Destroy" being deprecated is at the "End;" of the Create-Method?!?!?
That's not making a lick of sense to me

This is what I was asking for.

Just did a few tests:
The Warning to the "wrong" line appears only if
1) the Destructor is marked deprecated
2) There is a Constructor declared

Below shows only Warning for the second to last line "T.Destroy;"
Uncomment the Constructor and its code, you get the additional warning pointing to "end;" of the constructor
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. Uses SysUtils, Classes;
  3. Type
  4.   TMyClass = Class
  5.     Public
  6.       //Constructor Create;
  7.       Destructor Destroy;override;deprecated;
  8.   end;
  9. Var
  10.   T:TMyClass;
  11. //constructor TMyClass.Create;
  12. //begin
  13. //  Inherited;
  14. //end;
  15. destructor TMyClass.Destroy;
  16. begin
  17.   inherited Destroy;
  18. end;
  19. {Main Program}
  20. begin
  21.   T:=TMyClass.Create;
  22.   T.Destroy;   //Yes, yes... use Free
  23. end.

So alpine might be right regarding Auto-Destroy
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

alpine

  • Hero Member
  • *****
  • Posts: 1412
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Чебурашка

  • Hero Member
  • *****
  • Posts: 593
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Unexpected deprecated warnings at end of constructors
« Reply #10 on: September 06, 2023, 02:14:30 pm »
Destructor will be called automatically on exception raised in constructor. See the attached picture.

Ah ok I did not know this, so thank you for telling.

If I think about this I see some possible problems I never managed, releated to the classes structure. If one has an exception in the middle of the construction process, which is not atomic, and then the destructor is called automatically as you demonstrated, one should take care of signalling which structures where create successfully and which not, and the in the destructor he should release only the ones that were successfully created before the error in the constructor. Wow this could be a mess and need add extra information to manage the situation.

Generally I don't do operations during construction that could fail (i.e. access to db, network stuff), I only do other allocations/creations. This is why I never get worry about that, as the only issue in this case could be memory finished, but in that case theres not so much one can do. But this is just how I write classes, in general I understand the idea of calling the destructor in case of exception.
« Last Edit: September 06, 2023, 02:18:41 pm by Чебурашка »
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

alpine

  • Hero Member
  • *****
  • Posts: 1412
Re: Unexpected deprecated warnings at end of constructors
« Reply #11 on: September 06, 2023, 02:24:43 pm »
Destructor will be called automatically on exception raised in constructor. See the attached picture.

Ah ok I did not know this, so thank you for telling.

If I think about this I see some possible problems I never managed, releated to the classes structure. If one has an exception in the middle of the construction process, which is not atomic, and then the destructor is called automatically as you demonstrated, one should take care of signalling which structures where create successfully and which not, and the in the destructor he should release only the ones that were successfully created before the error in the constructor. Wow this could be a mess and need add extra information to manage the situation.
That is quite often overlooked, since most of the lines into destructor are usually xxx.Free and the class instantiation zeroes the memory, i.e. unallocated pointers (Nil) are not freed.
But if you use some other mechanisms than Create/Free pair, you definitely should have this in mind.

I should say that instances lifecycle management is a bit more complicated than it looks.
« Last Edit: September 06, 2023, 02:26:55 pm by alpine »
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Чебурашка

  • Hero Member
  • *****
  • Posts: 593
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Unexpected deprecated warnings at end of constructors
« Reply #12 on: September 06, 2023, 02:50:12 pm »
I should say that instances lifecycle management is a bit more complicated than it looks.

I have to be honest, in the years I realized that with this principles I generally survive quite smoothly:

1. Do not do any other action other than allocate memory in constructors (summarized in the phase "Constructors are to construct"). Blanking could be done as long as is not done using virtual methods (see 2). If unsure, don't do and make it after construction is completed.
2. Do not call virtual methods in constructors except in final classes, if language allows to make them final (i.e. the ones that cannot be overridden as they are final). In case you need to call virtual methods, do that after construction is completed, for example with builders (a class method that creates and then call the desired virtual method).

With 1 the only unpredictable problem remaining (programmer errors are not included, as they are not allowed) is out of memory. If that happens, prob my software has other more important problems to be solved.
With 2 I want to avoid the hell of accessing not instantiated members in descendants.

Nevertheless knowing about the details we are discussing is necessary.
« Last Edit: September 06, 2023, 03:09:22 pm by Чебурашка »
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

PascalDragon

  • Hero Member
  • *****
  • Posts: 6395
  • Compiler Developer
Re: Unexpected deprecated warnings at end of constructors
« Reply #13 on: September 07, 2023, 11:02:39 pm »
I was of the mind, that you should NEVER call "Destroy", but "Free" instead

There is nothing that forbids it. However calling Destroy directly on a Nil instance will lead to a crash while Free checks whether Self is Nil and only calls Destroy if that isn't the case.

Чебурашка

  • Hero Member
  • *****
  • Posts: 593
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Unexpected deprecated warnings at end of constructors
« Reply #14 on: September 08, 2023, 08:49:32 am »
I was of the mind, that you should NEVER call "Destroy", but "Free" instead

There is nothing that forbids it. However calling Destroy directly on a Nil instance will lead to a crash while Free checks whether Self is Nil and only calls Destroy if that isn't the case.

In all my life of programmer, the only situations in which I had a constructor to fail unexpectedly it was when I did in the constructor operations not related to construction (like accessing to resources, networking, files, databases and so on with the list of operation that could potentially fail), as I said in previous reply. Since I started to avoid them I had constructors failing because no memory left, but I can guarantee that in that case the real problem was not the constructor to fail but the cause of the memory depletion (too much open things or mem leaks). This is why, despite I always do Create try finally FreeAndNil end, this is just because I like it not because it necessary. I bet al lot of huge beers that if I was doing Create try finally Destroy end, I would get exactely the same results.
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

 

TinyPortal © 2005-2018