Can you give an example of how a type would be lost? I absolutely do not understand that reasoning. How a type would be “lost” (it would not be) and invalidate other variables (it would not?)
The more we discuss the more I think I am right.
Funnily enough, gfortran 13 does not say a word about explicit deallocation, which should be forbidden (the finalizer can be invoked).
module bugmod
implicit none
type value_t
end type
contains
pure subroutine reset_ptr(ptr)
class(value_t), intent(inout), pointer :: ptr
nullify(ptr)
end subroutine
pure subroutine dealloc_ptr(ptr)
class(value_t), intent(inout), pointer :: ptr
! hey, here we might call an impure finalizer
! but no word from gfortran
deallocate(ptr)
end subroutine
end module
class(animal_t), pointer :: john, clone
allocate(spider_t :: john)
clone => john
call fetch_ptr(john) ! john becomes undefined on entry
! the target and hence the dynamic type are lost
! clone changes too
If these were integers, everything would be fine (although it can potentially cause a memory leak, break associations, and is discouraged stylistically).
I’m just trying to play devil’s advocate here. Correct me if I’m wrong, but you are suggesting an amendment (in bold):
C1587 An INTENT (OUT) dummy argument of a pure procedure that is not a pointer, shall not be polymorphic or have a polymorphic allocatable ultimate component.
This code is invalid, but gfortran doesn’t catch it (yet). This is a quality of implementation issue. As written in the reply by @themos,
C15106 A statement that might result in the deallocation of a polymorphic entity is not permitted in a pure procedure.
Other compilers catch it.
ifx 2024.0:
/app/example.f90(14): error #5585: A statement that might result in the deallocation of a polymorphic entity is not permitted in a pure procedure.
deallocate(ptr)
------^
flang:
error: Semantic errors in /app/example.f90
/app/example.f90:14:18: error: Object in DEALLOCATE statement is not deallocatable
deallocate(ptr)
^^^
/app/example.f90:14:18: because: 'ptr' is polymorphic in a pure subprogram
deallocate(ptr)
I suggest reading F08/0033 in the N2121 document, keeping in mind the POINTER attribute added, and noting the exact point made there that you disagree with.
Note that finalization can also occur via DEALLOCATE of an ALLOCATABLE
or POINTER dummy argument that is not INTENT(IN).
Is this because a processor could choose to use garbage collection?
When the pointer became undefined, if the reference count were to drop to zero, the garbage collector would trigger a finalization (but this finalization can be impure and is undecidable at compile-time).
Somewhere along reading the Interp discussion, I thought that garbage collection (or some unspecified finite resource management) was being considered, yes, but I can’t go back and replay everything right now.
Is there possibility of garbage collection in Fortran? Now that would be quite shocking! But something feels not right there: I do not recollect any rules for possible lifetime of a garbage-collected object given in the standard. And there is no possible way to indicate which objects are managed by Fortran runtime: after all, we might share memory with C code, and having pointers (possibly) garbage corrected would be very C non-interoperable.
That is something that I completely did not expect! In this case yes, the “hole” seems to be purposedly left to allow garbage collection. It would not even cross my mind!
Thank you, definetely learned something new today!
When a pointer is deallocated its target is finalized. When an allocatable entity is deallocated, it is finalizedunless it is the variable in an intrinsic assignment statement. If an error condition occurs during deallocation, it is processor dependent whether finalization occurs
[…]
When a procedure is invoked, a nonpointer, nonallocatable, INTENT (OUT) dummy argument of that procedure is finalized before it becomes undefined. The finalization caused by INTENT (OUT) is considered to occur within the invoked procedure; so for elemental procedures, an INTENT (OUT) argument will be finalized only if a scalar or elemental final subroutine is available, regardless of the rank of the actual argument.
If an object is allocated via pointer allocation and later becomes unreachable due to all pointers associated with that object having their pointer association status changed, it is processor dependent whether it is finalized. If it is finalized, it is processor dependent as to when the final subroutines are called.
According to the last paragraph, the pointer intent(out) case can potentially trigger finalization of a derived type.
The Standard does not even mention “memory” in normative text (“Interoperability with C” Clause exempted), not even in the part about the SYNC MEMORY statement.
“Garbage” is a by-product of a certain implementation of Fortran semantics, so of course “garbage collection” is not specified by Fortran, in the same way that it does not specify operating temperature range of the hardware.