More on defined operator/assignment on an abstract type

View: New views
3 Messages — Rating Filter:   Alert me  

More on defined operator/assignment on an abstract type

by Rouson, Damian :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Janus,

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)



Re: More on defined operator/assignment on an abstract type

by Janus Weil-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

Re: More on defined operator/assignment on an abstract type

by Rouson, Damian :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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@...> 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
>
>