Re: [fpc-pascal] Freeing memory with exceptions

2023-05-21 Thread Michael Van Canneyt via fpc-pascal




On Sun, 21 May 2023, Hairy Pixels via fpc-pascal wrote:





On May 21, 2023, at 2:47 PM, Michael Van Canneyt via fpc-pascal 
 wrote:

Your example will leak memory in any case, even if there is no exception,
since you're not freeing the object anywhere..


doh, dumb example on my behalf.



Assuming the result of A is not used outside of Test, the following is the
only solution:

procedure Test;

var
A : TObject;
begin
 A:=TObject.Create;
 Try
   // call some code in other unit which raise an exception
   DoThis;
 finally
   A.Free
 end;
end;

You can try to use interfaces, they will be managed by the compiler.


This is what I was worried about, wrapping all functions or needing full ARC on 
all types. Very risk to opt in to this design I would say. I remain not a fan 
of exceptions. :)


They're used all over the place in the RTL and FCL, so you better take them
into account.

The compiler will do this wrapping anyway if you use ansistrings, so the
approach with e.g. a generic record will not cause a lot of overhead in most
cases.

Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Freeing memory with exceptions

2023-05-21 Thread Hairy Pixels via fpc-pascal



> On May 21, 2023, at 2:47 PM, Michael Van Canneyt via fpc-pascal 
>  wrote:
> 
> Your example will leak memory in any case, even if there is no exception,
> since you're not freeing the object anywhere..

doh, dumb example on my behalf.

> 
> Assuming the result of A is not used outside of Test, the following is the
> only solution:
> 
> procedure Test;
> 
> var
> A : TObject;
> begin
>  A:=TObject.Create;
>  Try
>// call some code in other unit which raise an exception
>DoThis;
>  finally
>A.Free
>  end;
> end;
> 
> You can try to use interfaces, they will be managed by the compiler.

This is what I was worried about, wrapping all functions or needing full ARC on 
all types. Very risk to opt in to this design I would say. I remain not a fan 
of exceptions. :)

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Freeing memory with exceptions

2023-05-21 Thread Michael Van Canneyt via fpc-pascal




On Sun, 21 May 2023, Hairy Pixels via fpc-pascal wrote:


I've never really used exceptions myself in Pascal (with the exception of 
breaking out of deeply recursive function calls) so I don't know all the rules.

In this example lets say you call Test() which allocates some memory and
then calls out to another function in another unit which raises (the
programmer doesn't know this because FPC doesn't mark the function as
throwing exceptions).  Now the Test() function will exit early before
freeing the memory.

What are you supposed to do here?  The only thing I can think of is to
wrap every function in try..finally which COULD raise an exception but
that's a huge mess because literally any function could raise.



procedure DoThis;
begin
 raise Exception.Create('dead');
end;

procedure Test;
begin
 TObject.Create;
 // call some code in other unit which raise an exception
 DoThis;
end;


Your example will leak memory in any case, even if there is no exception,
since you're not freeing the object anywhere..

Assuming the result of A is not used outside of Test, the following is the
only solution:

procedure Test;

var
 A : TObject;
begin
  A:=TObject.Create;
  Try
// call some code in other unit which raise an exception
DoThis;
  finally
A.Free
  end;
end;

You can try to use interfaces, they will be managed by the compiler.

Alternatively, using generics and management operators you can 
create a record that will automatically free the object at the 
end of the procedure.


Michael.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal