Hi Paul,

Am 10.02.22 um 13:25 schrieb Paul Richard Thomas via Fortran:
Conclusions on ifort:
(i) The agreement between gfortran, with the patch applied, and ifort is
strongest of all the other brands;
(ii) The disagreements are all down to the treatment of the parent
component of arrays of extended types: gfortran finalizes the parent
component as an array, whereas ifort does a scalarization. I have a patch
ready to do likewise.

Overall conclusions:
(i) Sort out whether or not derived type constructors are considered to be
functions;
(ii) Come to a conclusion about scalarization of parent components of
extended type arrays;
(iii) Check and, if necessary, correct the ordering of finalization in
intrinsic assignment of class arrays.
(iv) Finalization is difficult to graft on to existing pre-F2003 compilers,
as witnessed by the range of implementations.

I would be really grateful for thoughts on (i) and (ii). My gut feeling, as
remarked in the submission, is that we should aim to be as close as
possible, if not identical to, ifort. Happily, that is already the case.

I am really sorry to be such a bother, but before we think we should
do the same as Intel, we need to understand what Intel does and whether
that is actually correct.  Or not inconsistent with the standard.
And I would really like to understand even the most simple, stupid case.

I did reduce testcase finalize_38.f90 to an almost bare minimum,
see attached, and changed the main to

  type(simple), parameter   :: ThyType   = simple(21)
  type(simple)              :: ThyType2  = simple(22)
  type(simple), allocatable :: MyType, MyType2

  print *, "At start of program: ", final_count

  MyType = ThyType
  print *, "After 1st allocation:", final_count

  MyType2 = ThyType2
  print *, "After 2nd allocation:", final_count

Note that "ThyType" is now a parameter.

I tested the above and found:

Intel:
 At start of program:            0
 After 1st allocation:           1
 After 2nd allocation:           2

NAG 7.0:
 At start of program:  0
 After 1st allocation: 0
 After 2nd allocation: 0

Crayftn 12.0.2:
 At start of program:  2
 After 1st allocation: 2
 After 2nd allocation: 2

Nvidia 22.1:
 At start of program:             0
 After 1st allocation:            0
 After 2nd allocation:            0

So my stupid questions are:

- is ThyType invoking a constructor?  It is a parameter, after all.
  Should using it in an assignment invoke a destructor?  If so why?

  And why does Intel then increment the final_count?

- is the initialization of ThyType2 invoking a constructor?
  It might, if that is the implementation in the compiler, but
  should there be a finalization?

  Then ThyType2 is used in an intrinsic assignment, basically the
  same as the other one before.  Now what is the difference?

Are all compilers correct, but I do not see it?

Someone please help!

Best regards

Paul


Cheers,
Harald
module testmode
  implicit none

  type :: simple
     integer :: ind
  contains
    final :: destructor1
  end type simple

  integer :: final_count = 0

contains

  subroutine destructor1(self)
    type(simple), intent(inout) :: self
    final_count = final_count + 1
  end subroutine destructor1

end module testmode

program test_final
  use testmode
  implicit none
  type(simple), parameter   :: ThyType   = simple(21)
  type(simple)              :: ThyType2  = simple(22)
  type(simple), allocatable :: MyType, MyType2

  print *, "At start of program: ", final_count

  MyType = ThyType
  print *, "After 1st allocation:", final_count

  MyType2 = ThyType2
  print *, "After 2nd allocation:", final_count

end program test_final

Reply via email to