Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Procedure Pointer Q2

dundar11
Beginner
661 Views
Hi,
My previous post has two questions and I believe I couldn't state the problem well. Here is a more clear version of my problem.
Here is the test case:
[fortran]module procedure_pointer
  implicit none
 type, abstract :: parent_type
   real(8) :: tol
   procedure() , nopass, pointer :: func_pointer
 end type

 type ,extends(parent_type) :: child_type
   integer :: iter
 end type

 type function_type
  real(8) :: aux
  contains
  procedure,nopass :: func
 end type
contains
 function func(x) result(y)
 real(8) , intent(in) :: x
 real(8) :: y
 y=x*x
 end function

end module procedure_pointer


program procedure_pointer_test
  use procedure_pointer
  implicit none
  type(child_type) :: child
  type(function_type), target :: son
  real(8) :: func_result,x[/fortran]
[fortran]  x=3.2d0
   child%func_pointer=> son%func
  func_result=child%func(x)
  print*,'Function result :', func_result

end program procedure_pointer_test[/fortran]
And the compiler error is:
test.f90(34): error #8191: The procedure target must be a procedure or a procedure pointer. [FUNC]
child%func_pointer=> son%func
----------------------------^
test.f90(35): error #6460: This is not a field name that is defined in the encompassing structure. [FUNC]
func_result=child%func(x)
--------------------^
test.f90(35): error #6158: The structure-name is invalid or is missing. [CHILD]
func_result=child%func(x)
--------------^
compilation aborted for test.f90 (code 1)
test.f90(34): error #8191: The procedure target must be a procedure or a procedure pointer. [FUNC] child%func_pointer=> son%func----------------------------^test.f90(35): error #6460: This is not a field name that is defined in the encompassing structure. [FUNC] func_result=child%func(x)--------------------^test.f90(35): error #6158: The structure-name is invalid or is missing. [CHILD] func_result=child%func(x)--------------^compilation aborted for test.f90 (code 1)
0 Kudos
5 Replies
Steven_L_Intel1
Employee
661 Views
Ah, I see. You cannot assign a type-bound procedure as a function pointer. The target needs to be a component of the type or an external, module, dummy or intrinsic procedure (some limits on intrinsics.)
0 Kudos
dundar11
Beginner
661 Views
I could assign a module procedure to this pointer and it works. But as you said I can't assign another type's bound procedure to that pointer...
so sad..
Is there any plan to implement this or it just doesnt make sense at all?
Thanks.
0 Kudos
Steven_L_Intel1
Employee
661 Views
No, we won't be implementing that. It doesn't really make sense as the point of a type-bound procedure is typically that the derived type object gets passed as one of the arguments. With a pointer to it, what exactly are you passing?
0 Kudos
dundar11
Beginner
660 Views
In my design
there will be two derived types
1- optimizer
2- cost function
optimizer will hold some settings for optimization algorithm and the implementation of the algorithm itself.
and a pointer for a costfunction
cost function is little bit more complex actually serves as a driver and there will be different cost functions.
so i want to design cost function as a derived type and this will help me to store some settings with it in a more compact way. On top of them I can manage these settings and during the runtime I tried to link
optimizers pointer to call costfunction derived types cost function. In this case I could chose which cost_function to use. Does it make sense?
But now I chose a different way:
I wrote a generic cost function in a seperate module which has different derived types for different cost function choices. With user's settings I can pick the correct cost function derived type.
I assigned generic cost function to optimizer's pointer and it works.
My main aim was to gain as much flexiblity as I can.
0 Kudos
John4
Valued Contributor I
661 Views
By using the NOPASS attribute in the type-bound procedure, you're actually saying that the components in the function_type derived type are not needed at all by func. So it seems that you want to design based purely on syntactic sugar ---i.e., just for the sake of invoking the function as something%func(x) instead of just func(x).

Instead of a procedure pointer, it seems that what you really want is a pointer to a derived type, so that child_type can still have access to the components of function_type:

[fortran]module procedure_pointer
    implicit none

    type function_type
        real(8) :: aux = 13
    contains
        procedure,nopass :: func
    end type

    type, abstract :: parent_type
        real(8) :: tol
        class(function_type), pointer :: cost => NULL()
    end type

    type ,extends(parent_type) :: child_type
        integer :: iter
    end type

contains
    function func(x) result(y)
        real(8) , intent(in) :: x
        real(8) :: y
        y=x*x
    end function
end module procedure_pointer

program procedure_pointer_test
    use procedure_pointer
    implicit none
    type(child_type) :: child
    type(function_type), target :: son
    real(8) :: func_result,x

    x=3.2d0
    child%cost=> son
    func_result = child%cost%func(x)
    print*,'Function result :', func_result
    print*,'Function aux :', child%cost%aux
end program procedure_pointer_test[/fortran]

0 Kudos
Reply