Quantcast
Channel: Intel® Fortran Compiler for Linux* and macOS*
Viewing all articles
Browse latest Browse all 2583

Error extending extended types

$
0
0
I am trying to use the object orientated features of Fortran (Essentially, what I want to be able to do is to get an array of arraies, where each element of the outer array has a different size), and I have run into the following error,Is this a bug?>
Undefined symbols for architecture x86_64:"_valout_", referenced from:
      _TBPLIST_PACK_3.0.1 in ifortgrMMR7.o
ld: symbol(s) not found for architecture x86_640

I know that I have defined ValOut, and this appears to be a bug with the compiler when you extend an extended type which has allocatable components inside.

I have attached below the code to show this, together with the compilation command.   I am using ifort version 17.0.2.   I have tested it against ifort version 17.0.2 and ifort version 16.0.0, both of which give the same error.   However, when I tested it with gfortran (gcc version  6.1.0) it worked.

What the code is is an abstract type (a Feature) which has a deferred procedure (ValOut).   This takes as input the class (Feature) and a set of real values (vauesOut).   

module FeatureMod
  use iso_fortran_env

  type, abstract:: feature
      character(len=:), allocatable:: name
    contains
      procedure (ValOut), deferred :: getAllValues
  end type

  interface
    subroutine ValOut(self, valuesOut)
      use iso_fortran_env
      import Feature
    class(Feature), intent(in):: self
      real(real64), dimension(:):: valuesOut
    end subroutine ValOut

  end interface

contains

end module FeatureMod

I now define an extension of the type Feature where I override ValOut. For this extension, I set ValOut to be 1.

module FirstFeatureMod
use iso_fortran_env
use FeatureMod
implicit none

   type, extends(feature):: secondType
     real, dimension(:), allocatable::r
     contains
       procedure:: getAllValues => getAllValuesSecond
   end type secondType

   contains

     subroutine getAllValuesSecond(self, valuesOut)
       class(secondType), intent(in):: self
       real(real64), dimension(:):: valuesOut

       valuesOut = 1
    end subroutine
end module FirstFeatureMod

I also define a thirdType (extending second type), and a fifthType(extending secondType).   For these functions, I override ValOut to set the output to be 3 and 5 respectively.

module SecondFeatureMod
  use FirstFeatureMod

  type, extends(secondType):: thirdType
    integer:: k=6
  contains
    procedure:: getAllValues => getAllValuesThird
  end type thirdType

  type, extends(secondType):: fifthType
    integer:: l=22
    contains
    procedure:: getAllValues => getAllValuesFifth
    end type

  contains
     subroutine getAllValuesThird(self, valuesOut)
       class(thirdType), intent(in):: self
       real(real64), dimension(:):: valuesOut

       valuesOut = 3
    end subroutine
     subroutine getAllValuesFifth(self, valuesOut)
       class(fifthType), intent(in):: self
       real(real64), dimension(:):: valuesOut

       valuesOut = 5
    end subroutine
end module SecondFeatureMod

Because I want an array of these, I define class which holds a pointer to a Feature class.   This allows me to get an array of these arrays by defining ar array of the type holding the pointer.

module ListFeatureMod
  use FeatureMod
  use FirstFeatureMod



  type:: checkType
    class(feature), pointer:: l
    contains
      procedure:: setType
  end type

  type:: listOfCheck
    type(checkType), dimension(:), allocatable:: list
  contains
    procedure, pass:: allocateTypes
  end type

contains
  subroutine allocateTypes(self, intIn)
    class(listOfCheck), intent(inout):: self
    integer, intent(in):: intIn

    allocate(self%list(intIn))

  end subroutine allocateTypes

  subroutine setType(self, typeIn)
  class(checkType), intent(inout):: self
  class(feature), intent(in):: typeIn

    allocate(self%l, source=typeIn)
  end subroutine setType

end module 

Finally, I wrote a short program to test this, where I define an array of length 3, I set each element of the array to be a different derived type, and I write out the results.    The expected results are simply 3,3,3\n1,1,1\n5,5,5.

program test

  use FeatureMod
  use FirstFeatureMod
  use SecondFeatureMod
  use ListFeatureMod
  integer:: N, i

  type(thirdType), target:: b
  type(secondType), target:: c
  type(fifthType), target:: e
  type(listOfCheck):: k
  real(real64), dimension(3)::r


  call k%allocateTypes(3)


  call k%list(1)%setType(b)
  call k%list(2)%setType(c)
  call k%list(3)%setType(e)

  do i = 1, 3
    call k%list(i)%l%getAllValues(r)
    write(*,*) r
  end do

contains

end program

But this doesn't compile.   I am trying to compile with no special flags 

ifort Feature.f90 FirstFeature.f90 SecondFeature.f90 ListFeature.f90 FeatureContainer.f90 

 

Is this a bug?   Does Fortran allow me to do what I want to do?   If not, is there another way to get this to work?

This bug doesn't appear if none of the types have allocatable components, so it might be possible to get around it by using something like

type, abstract:: feature(length)
integer, len:: length
contains
.
.
end type

type, extends(feature):: secondFeature
   real(real64), dimension(lenght):: values
  contains
    .
    .
    .
end type

But I have had some serious issues trying to get the integer, len:: features of ifort to work.

Any help would be much appreciated.

AttachmentSize
Downloadapplication/ziptestEffectList.zip901.75 KB

Zone: 

Thread Topic: 

Bug Report

Viewing all articles
Browse latest Browse all 2583

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>