From: Neil on
In Fortran 95 I employed the following technique for destroying a
derived
type object that had default initialized components:

subroutine destroy (this)
type(my_type), intent(inout) :: this
type(my_type) :: default
! free all the resources belonging to the components of THIS
this = default
end subroutine

The final line took care of automatically assigning the default
initialization
values to the components of the object; I didn't have to assign them
explicitly and run the risk of inadvertently assigning different
values than
were used in the type definition.

In F2003 I'd like to make the destroy subroutine a TBP, which requires
the argument being of class(my_type), but there is no intrinsic
assignment
to a class variable, and that final magic line no longer works.

Anybody have some sage advice on how to approach this? Of course
I could make a defined assignment, but I'm really loath to bother with
that unless I have to (or is it advisable to always make a defined
assignment for derived types regardless?) Eventually my aim is to
make
such routines actual finalizers (does that change the situation?) but
my
compiler hasn't implemented those yet.

Cheers,
Neil
From: Reinhold Bader on
Hello,

Am 13.02.2010 15:24, schrieb Neil:
> In Fortran 95 I employed the following technique for destroying a
> derived
> type object that had default initialized components:
>
> subroutine destroy (this)
> type(my_type), intent(inout) :: this
> type(my_type) :: default
> ! free all the resources belonging to the components of THIS
> this = default
> end subroutine
>
> The final line took care of automatically assigning the default
> initialization
> values to the components of the object; I didn't have to assign them
> explicitly and run the risk of inadvertently assigning different
> values than
> were used in the type definition.

Note that it would be sufficient to simply use an INTENT(OUT) argument
to achieve the same effect; both methods will not work well
for dynamic type components, especially those with the POINTER attribute
aliased to an anonymous target (memory leaks will typically result).

>
> In F2003 I'd like to make the destroy subroutine a TBP, which requires
> the argument being of class(my_type), but there is no intrinsic
> assignment
> to a class variable, and that final magic line no longer works.

As indicated above, the line is not really needed. Note however that
if you wish to also change the type of the entity during computation
then DEALLOCATE in a scope where your polymorphic entity has the
ALLOCATABLE or POINTER attribute is more appropriate.
>
> Anybody have some sage advice on how to approach this? Of course
> I could make a defined assignment, but I'm really loath to bother with
> that unless I have to (or is it advisable to always make a defined
> assignment for derived types regardless?) Eventually my aim is to
> make
> such routines actual finalizers (does that change the situation?) but
> my

finalizers require a non-polymorphic "this" argument due to the inheritance
mechanism, which might invoke a sequence of finalizers on parent components.
However they are certainly more suitable if dynamic components need to be
properly cleaned up.

> compiler hasn't implemented those yet.
>
> Cheers,
> Neil

Best Regards
Reinhold
From: Neil on
On Feb 13, 9:56 am, Reinhold Bader <Ba...(a)lrz.de> wrote:
> Am 13.02.2010 15:24, schrieb Neil:
> > In Fortran 95 I employed the following technique for destroying a
> > derived
> > type object that had default initialized components:
>
> > subroutine destroy (this)
> >   type(my_type), intent(inout) :: this
> >   type(my_type) :: default
> >   ! free all the resources belonging to the components of THIS
> >   this = default
> > end subroutine
>
> > The final line took care of automatically assigning the default
> > initialization
> > values to the components of the object;  I didn't have to assign them
> > explicitly and run the risk of inadvertently assigning different
> > values than
> > were used in the type definition.
>
> Note that it would be sufficient to simply use an INTENT(OUT) argument
> to achieve the same effect;

Not true. If the type had a pointer component default initialized to
null, then that component of the dummy argument would be retargeted to
null on entry -- without doing anything about deallocating the
original
target -- and you'd end up with a memory leak. It's important that it
be intent(inout).
From: Reinhold Bader on
Am 13.02.2010 23:06, schrieb Neil:
> On Feb 13, 9:56 am, Reinhold Bader <Ba...(a)lrz.de> wrote:
>> Am 13.02.2010 15:24, schrieb Neil:
>>> In Fortran 95 I employed the following technique for destroying a
>>> derived
>>> type object that had default initialized components:
>>
>>> subroutine destroy (this)
>>> type(my_type), intent(inout) :: this
>>> type(my_type) :: default
>>> ! free all the resources belonging to the components of THIS
>>> this = default
>>> end subroutine
>>
>>> The final line took care of automatically assigning the default
>>> initialization
>>> values to the components of the object; I didn't have to assign them
>>> explicitly and run the risk of inadvertently assigning different
>>> values than
>>> were used in the type definition.
>>
>> Note that it would be sufficient to simply use an INTENT(OUT) argument
>> to achieve the same effect;
>
> Not true. If the type had a pointer component default initialized to
> null, then that component of the dummy argument would be retargeted to
> null on entry -- without doing anything about deallocating the
> original
> target -- and you'd end up with a memory leak.

Agreed (in fact I indicated just this in my earlier posting). Let me
stress again that your construction has just the same problem, unless you
overload the assignment operator to take care of required deallocations.
Having a finalizer (which would be invoked for INTENT(OUT)) would be a more
elegant solution of course.

Regards

> It's important that it
> be intent(inout).



From: Jim Xia on
In Fortran 2003, you should use final routines to do the clean up --
that's what they're there for. The finalizers are type bound, but the
dummy has to be TYPE (nonpolymorphic). You can keep your destroy
routine as a final subroutine.

Cheers,

Jim