For what it is worth.
On 2/10/22 11:49 AM, Harald Anlauf via Fortran wrote:
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.
----- snip ----
Ignore whether Thytype is a Parameter. Regardless Mytype and Mytype2
are allocated upon the assignment. Now if these are never used
anywhere, it seems to me the deallocation can be done by the compiler
anywhere after the last time it is used. So it can be either after the
PRINT statement before the end if the program or right after the
assignment before your PRINT statements that examine the value of
final_count. I think the result is arbitrary/undefined in your reduced
test case
I do not have the Intel compiler yet, so I was going to suggest see what
it does if your test program prints something from within MyType and
MyType2 after all your current print statements at the end. Try this
variation of the main program.
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
print *, MyType%ind, MyType2%ind, final_count
deallocate(Mytype)
print *, MyType%ind, MyType2%ind, final_count
deallocate(Mytype2)
print *, MyType%ind, MyType2%ind, final_count
end program test_final
I get with trunk:
$ ./a.out
At start of program: 0
After 1st allocation: 0
After 2nd allocation: 0
21 22 0
0 22 1
0 0 2
Which makes sense to me.
Regards,
Jerry