More on defined operator/assignment on an abstract type

Rouson, Damian rouson@sandia.gov
Wed Nov 11 08:17:00 GMT 2009


Thanks, Janus.  The code below compiles.  I¹ll  move on to implementing the
extended type and see if I can work in a CLASS IS test.

Damian

module foo_module
  implicit none
  private  ! Hide everything by default
  public :: foo

  type ,abstract :: foo
  contains
    procedure(times_interface) ,deferred :: times
    procedure(assign_interface) ,deferred :: assign
    generic :: operator(*) => times
    generic :: assignment(=) => assign
  end type

  abstract interface
    function times_interface(this,factor) result(product)
      import :: foo
      class(foo) ,intent(in)  :: this
      class(foo) ,allocatable :: product
      real, intent(in) :: factor
    end function 
    subroutine assign_interface(lhs,rhs)
      import :: foo
      class(foo) ,intent(inout) :: lhs
      class(foo) ,intent(in)    :: rhs
    end subroutine
  end interface

contains

  subroutine scale_this(this,scale)
    class(foo) :: this
    real, intent(in) :: scale
    this = this*scale        ! Preferred implementation
    this = this%times(scale) ! Alternate implementation
  end subroutine

end module



On 11/9/09 12:37 AM, "Janus Weil" <janus@gcc.gnu.org> wrote:

> Hi Damian,
> 
>> It appears the code I submitted with PR 41556 still gives errors (different
>> from the previous errors) with gcc 4.5.0 20091106.  The code and error
>> messages are below.
>> 
>> Damian
>> 
>> $ cat abstract.f03
>> module foo_module
>>  implicit none
>>  private  ! Hide everything by default
>>  public :: foo
>> 
>>  type ,abstract :: foo
>>  contains
>>    procedure(times_interface) ,deferred :: times
>>    generic :: operator(*) => times
>>  end type
>> 
>>  abstract interface
>>    function times_interface(this,factor) result(product)
>>      import :: foo
>>      class(foo) ,intent(in)  :: this
>>      class(foo) ,allocatable :: product
>>      real, intent(in) :: factor
>>    end function
>>  end interface
>> 
>> contains
>> 
>>  subroutine scale_this(this,scale)
>>    class(foo) :: this
>>    real, intent(in) :: scale
>>    this = this*scale        ! Preferred implementation
>>    this = this%times(scale) ! Alternate implementation
>>  end subroutine
>> 
>> end module
>> $ /usr/local/gfortran/bin/gfortran-4.5 abstract.f03
>> abstract.f03:26.4:
>> 
>>    this = this*scale        ! Preferred implementation
>>    1
>> Error: Variable must not be polymorphic in assignment at (1)
>> abstract.f03:27.4:
>> 
>>    this = this%times(scale) ! Alternate implementation
>>    1
>> Error: Variable must not be polymorphic in assignment at (1)
> 
> I think in this case gfortran is actually right to reject it.
> Performing an assignment on a polymorphic variable is only permitted
> if the declared type has a defined assignment operator, which your
> example does not have (this is also confirmed by ifort and nagfor).
> 
> Cheers,
> Janus
> 
> 




More information about the Fortran mailing list