Community
cancel
Showing results for 
Search instead for 
Did you mean: 
4 Views

Type Bound Generic Assignment Bug Using Intrinsic Assignments

Hello everybody,

I assume I ran into a bug with Intel Fortran 19.0.5.281. I ran into this problem writing a reference counting scheme.

The problem can be tested with this program:

 

MODULE Classes

    IMPLICIT NONE

    TYPE Inner_
       INTEGER                       :: iCount=0
    END TYPE

    TYPE Inner
       CLASS(Inner_), POINTER         :: this => NULL()
       CONTAINS
       PROCEDURE                     :: init
       PROCEDURE                     :: assignMe
       GENERIC                       :: assignment(=) => assignMe 
       FINAL                         :: deleteIt
    END TYPE

    TYPE user
       TYPE(Inner)    :: mInner
    END TYPE
CONTAINS

   SUBROUTINE init(self)
      CLASS(Inner), INTENT(OUT)      ::  self

      ALLOCATE(Inner_ :: self%this)
      self%this%icount=1
   END SUBROUTINE 

   SUBROUTINE deleteIt(self)
      TYPE(Inner)          ::  self
      IF(ASSOCIATED(self%this)) THEN
         self%this%icount=self%this%icount-1
         IF(self%this%icount==0)DEALLOCATE(self%this)
      ENd IF
   END SUBROUTINE

   ELEMENTAL IMPURE SUBROUTINE assignMe(self, input)
      CLASS(Inner), INTENT(OUT)      ::  self
      CLASS(Inner), INTENT(IN)      ::  input
      
      IF(ASSOCIATED(input%this))THEN
         self%this=>input%this
         self%this%icount=self%this%icount+1
      END IF
   END SUBROUTINE

END MODULE

PROGRAM test

   USE Classes

   IMPLICIT NONE

WRITE(*,*)"Assign Each Element(Works as expected)"
   BLOCK
      TYPE(user)          :: mOuter(2), reassigned(2)

      CALL mOuter(1)%mInner%init()
      CALL mOuter(2)%mInner%init()
      reassigned(1)=mOuter(1)
      reassigned(2)=mOuter(2)
      WRITE(*,*)"mOuter(1)    ", mOuter(1)%mInner%this%iCount , "EXPECTING 2"
      WRITE(*,*)"mOuter(2)    ", mOuter(2)%mInner%this%iCount , "EXPECTING 2"
      WRITE(*,*)"reassigned(1)", reassigned(1)%mInner%this%iCount , "EXPECTING 2"
      WRITE(*,*)"reassigned(2)", reassigned(2)%mInner%this%iCount , "EXPECTING 2"
   END BLOCK
WRITE(*,*)
WRITE(*,*)"Assign intrinsic vector(Does not increment reference count)"
   BLOCK
      TYPE(user)          :: mOuter(2), reassigned(2)

      CALL mOuter(1)%mInner%init()
      CALL mOuter(2)%mInner%init()
      reassigned=mOuter
      WRITE(*,*)"mOuter(1)    ", mOuter(1)%mInner%this%iCount , "EXPECTING 2"
      WRITE(*,*)"mOuter(2)    ", mOuter(2)%mInner%this%iCount , "EXPECTING 2"
      WRITE(*,*)"reassigned(1)", reassigned(1)%mInner%this%iCount , "EXPECTING 2"
      WRITE(*,*)"reassigned(2)", reassigned(2)%mInner%this%iCount , "EXPECTING 2"
   END BLOCK


END PROGRAM

The produced output is:

 Assign Each Element(Works as expected)
 mOuter(1)               2 EXPECTING 2
 mOuter(2)               2 EXPECTING 2
 reassigned(1)           2 EXPECTING 2
 reassigned(2)           2 EXPECTING 2

 Assign intrinsic vector(Does not increment reference count)
 mOuter(1)               1 EXPECTING 2
 mOuter(2)               1 EXPECTING 2
 reassigned(1)           1 EXPECTING 2
 reassigned(2)           1 EXPECTING 2

 

As it can be seen, using an element by element assignment increases the counter by calling the type bound assignment.

However using a vector assignment for the outer class does not call the type bound assignment function.

I would expect the vector assignment to be a shorthand notation for the element by element assignment. Is this correct?

 

Best regards

Flo

0 Kudos
1 Reply
Highlighted
Retired Employee
4 Views

I would expect the vector

I would expect the vector assignment to be a shorthand notation for the element by element assignment. Is this correct?

Yes. See paragraph 2 of Fortran 2018 section 10.2.1.4 (Defined Assignment).

A subroutine defines the defined assignment x1 = x2 if
... (5) either
(a) the ranks of x1 and x2 match those of d1 and d2 or 
(b) the subroutine is elemental, x2 is scalar or has the same rank as x1, and there is no other
 subroutine that defines the assignment.

--
Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos