In this question: Fortran Functions with a pointer result in a normal assignment, it is stated that functions returning pointers are not recommended.
My question concerns constructors of user defined types. Consider the code below:
program PointTest
use PointMod, only: PointType
implicit none
class(PointType), allocatable :: TypeObject
TypeObject = PointType(10)
end program PointTest
module PointMod
implicit none
type PointType
real(8), dimension(:), allocatable :: array
contains
final :: Finalizer
end type PointType
interface PointType
procedure NewPointType
end interface PointType
contains
function NewPointType(n) result(TypePointer)
implicit none
integer, intent(in) :: n
type(PointType), pointer :: TypePointer
allocate(TypePointer)
allocate(TypePointer%array(n))
end function NewPointType
subroutine Finalizer(this)
implicit none
type(PointType) :: this
print *, 'Finalizer called'
end subroutine Finalizer
end module PointMod
In the code, I have defined a type with a constructor that allocates the object and then allocates an array in the object. It then returns a pointer to the object.
If the constructor just returned the object, the object and the array would be copied and then deallocated (at least with standard compliant compilers). This could cause overhead and mess with our memory tracking.
Compiling the above code with ifort gives no warnings with -warn all (except unused variable in the finalizer) and the code behaves the way I expect. It also works fine with gfortran, except I get a warning when using -Wall
TypeObject = PointType(10)
1
Warning: POINTER-valued function appears on right-hand side of assignment at (1) [-Wsurprising]
What are the risks of using constructors like these? As far as I can tell, there will be no dangling pointers and we will have more control on when objects are allocated. One workaround that would achieve the same result is to explicitly allocate the object and turn the constructor into a subroutine that sets variables and does the allocation of array, but it looks a lot less elegant. Are there other solutions? Our code is in the Fortran 2008 standard.