Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29284 Discussions

Abstract interface and procedure declaration for character function

ender01
New Contributor I
601 Views

Hello all,

I'm trying to construct an interface for a character function that returns a string whose length is determined by the input object, a derived type foo:

type foo

integer(kind=1) :: size
character, dimension(:), allocatable :: token
procedure(charStr_func), pointer :: fooBar
end type foo

The function, bar, returns a string constructed by concatenating the elements of foo%token and I want to size the string as an auotmatic object:

function bar(foo_bar) result(bar_foo)
type(foo), intent(in) :: foo_bar
character(len = foo_bar%size) :: bar_foo
...
end function bar

I want to define a function pointer so I define the abstract interface

abstract interface
function charStr_func(foo_bar)
import
type(foo), intent(in) :: foo_bar
character(len=foo_bar%size) :: charStr_func
end function charStr_func
end interface

So far so good, then I try to associate the pointer:

type(foo) :: foo1
...
foo1%fooBar => bar

and I get the compilation error #8178: The procedure pointer and the procedure target must have matching arguments. (This occurs regardless of whether or not I use the result clause in the function definition).

Any ideas?

Thanks,

Rich

0 Kudos
4 Replies
Steven_L_Intel1
Employee
601 Views

Is bar a contained procedure? If so, this is possibly bug DPD200050116, but the fix for that is not yet in a scheduled update. It would help if you could provide a short but complete example of the problem.

0 Kudos
ender01
New Contributor I
601 Views

Is bar a contained procedure? If so, this is possibly bug DPD200050116, but the fix for that is not yet in a scheduled update. It would help if you could provide a short but complete example of the problem.

Hi Steve,

Yes, bar is a contained procedure. The complete module looks like this:

[cpp]module foo_Mod
   use Basic_Numerics   ! Module defining kind parameters among other things
   implicit none

   private
   public :: foo, assignment(), len, ..., bar, ...

   !  Define object
   type foo
      integer(kind=I_LO) :: size
      character(len=1), dimension(:), allocatable :: token
      procedure(charStr_func), pointer :: getToken
   end type foo

   !  Define interfaces
   ...

   interface len
      module procedure get_Size
   end interface
   ...

   !  Define abstract interfaces for type-bound procedures
   abstract interface
      function charStr_func(foo_var)
         import
         type(foo), intent(in) :: foo_var
         character(len=len(foo_var)) :: charStr_func
      end function charStr_func
   end interface

   !  Define module procedures
   contains
      ...
      function get_Token(foo_var)  result(foo_Token)
         
         type(symbol), intent(in)  :: foo_var
         character(len=len(base_Symbol)) :: foo_Token
         integer(kind=I_LO) :: kount
			
         !  Loop over elements of token and assemble the output character string
         foo_Token(1:len(foo_var)) = foo_var%token(1)
         do kount = 2,len(foo_var)
            current_Token(1:len(foo_var)) = trim(foo_Token)// &
foo_var%token(kount) end do end function get_Token pure function get_Size(foo_var) result(foo_Size) type(foo), intent(in) :: foo_var integer(kind=I_LO) :: foo_Size ! Extract token size foo_Size = foo_var%size end function get_Size ... end module foo_Mod[/cpp]

Let me know if this is complete enough. Thanks!

Rich

0 Kudos
Steven_L_Intel1
Employee
601 Views

There's no pointer assignment here, but from what you've posted it looks like the same bug to me. I'll follow up with development.

0 Kudos
ender01
New Contributor I
601 Views

There's no pointer assignment here, but from what you've posted it looks like the same bug to me. I'll follow up with development.

I just noticed that I had omitted the module procedure doing the pointer assignment. This procedure is contained in the above module as well:

[cpp]subroutine set_Token(foo_var,foo_Token)

   type(symbol), intent(inout)  :: foo_var
   character(len=*), intent(in) :: foo_Token
			
   integer(kind=I_LO) :: kount, new_Size
   logical :: alloc_Flag, assoc_Flag
			
   !  Get length of new token
    new_Size = len(foo_Token)
			
   !  As this may be a redefinition of the foo object check allocation
   !  status and set alloc_Flag to true if token must be allocated
   alloc_Flag = .not. allocated(foo_var%token)
         
   !  Test that any allocation is appropriate
   if (.not. alloc_Flag) then
      !  Token has already been allocated, is it the right size
      alloc_Flag = len(foo_var) /= new_Size
            
      !  If token has the wrong size, deallocate
      if (alloc_Flag) then
         deallocate(foo_var%token)
      end if
   end if

   !  If necessary, resize and allocate storage array
   if (alloc_Flag) then
      foo_var%size = new_Size
      allocate(foo_var%token(new_Size))
   end if

   !  Assign new token to base symbol object
   do kount = 1,foo_var%size
       foo_var%token(kount) = foo_Token(kount:kount)
   end do
         
   !  If not already associated, want to have function pointers
   !  set.  Set assoc_Flag to .True. if function pointer needs
   !  to be associated
   assoc_Flag = .not. associated(foo_var%getToken)
   if (assoc_Flag) then
      foo_var%getToken => get_Token
   end if

end subroutine set_Token[/cpp]

Thanks again,

Rich

0 Kudos
Reply