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

procedure pointer with implicit interface problem

Juan_Pablo_S_1
Beginner
1,228 Views

Hello. I get the following output* with the code below. Am I using the pointer procedure with implicit interface in the correct way?

procedure pointer with implicit interface:

7781897

procedure pointer with explicit interface:

5

[fortran]

program main
implicit none
procedure(),pointer :: prA
procedure(w_interface),pointer :: prB
abstract interface
subroutine w_interface(j)
implicit none
integer,intent(in),dimension(:) :: j
end subroutine
end interface
integer,dimension(5) :: i


prA=>print_size
prB=>print_size

print*, 'procedure pointer with implicit interface:'
call prA(i)

print*, 'procedure pointer with explicit interface:'
call prB(i)
contains
subroutine print_size(j)
implicit none
integer,intent(in),dimension(:) :: j
print*, size(j)
end subroutine
end program [/fortran]

*compiled with ifort 13.0.1 under linux mint 14

0 Kudos
4 Replies
Steven_L_Intel1
Employee
1,229 Views

Your call with an implicit interface is incorrect - the subroutine requires an explicit interface. I think the compiler should catch the error in this case and will ask the developers to add a check.

0 Kudos
Juan_Pablo_S_1
Beginner
1,229 Views

Besides the fact that in my previous example  the compiler gives no errors and flags, in the following code*, the subroutine subA, in which the input array has an assigned size, gives the supposedly "correct" output ' 7 5 3' . On the other hand, the subroutine subB  gives an empty line as output. I am afraid that I am not getting the idea behind procedure pointers with no explicit interface. According to the answer of Steve L. they are not legal at all, or did I misunderstood him?

[fortran] program main
implicit none
procedure(),pointer :: pr
integer,dimension(3) :: id
id=(/7,5,3/)
pr=>subA
call pr(id)
pr=>subB
call pr(id)
contains
subroutine subA(k)
implicit none
integer,dimension(3),intent(in) :: k
print*, k
end subroutine
subroutine subB(k)
implicit none
integer,dimension(:),intent(in) :: k
print*, k
end subroutine

end program [/fortran] 

*compiled with ifort 13.0.1 under linux mint 14

0 Kudos
Steven_L_Intel1
Employee
1,229 Views

Let me try to explain again.

Procedure pointers are not really the issue here - it's all about explicit interfaces and when they are required. Certain language features, when used in a procedure, require an explicit interface to be visible to the caller. One of these is a dummy argument that is a deferred-shape array, as in your subB in the most recent post. If you call this routine, the language requires that an explicit interface be visible to the caller because the compiler has to pass the argument differently. subA, on the other hand, doesn't use any of the features requiring an explicit interface. If you called either subA or subB directly from the program, that would be fine because being a contained procedure establishes an explicit interface. But lets say that you had something like this:

[fortran]
program main
integer, dimension(3) :: id
id=(/7,5,3/)
call subB(id)
end
subroutine subB(k)
integer, dimension(:), intent(in) :: k
print *, k
end subroutine
[/fortran]

Now subB is an external procedure and therefore it does not create an explicit interface automatically. This program is not legal because no explicit interface is visible to the caller of subB. I wrote a couple of articles some time ago on the general topic that you may find useful: Doctor Fortran Gets Explicit! and Doctor Fortran Gets Explicit - Again!.

Now let's introduce the procedure pointers. You can declare procedure pointers to have either an implicit interface or an explicit interface. In the first post, prA had an implicit interface and prB an explicit interface. The programmer is required to make sure that if a call is made through a procedure pointer to a routine that requires an explicit interface, such as print_size in the first example or subB in the second, that the pointer be declared with a matching explicit interface. This is the rule you violated in both examples when using the pointer with an implicit interface, but our compiler didn't catch the error. In both of these programs it could conceivably do so as it can "see" the target and determine that an explicit interface is required, but it doesn't do so now. I have asked the developers to add that check. However, there are cases where the compiler can't see the target procedure. Our generated interface checking feature could help here in many cases, but not, for example, if the target was in a library or not compiled as part of the application build.

Does this help?

0 Kudos
Juan_Pablo_S_1
Beginner
1,229 Views

Thank you  for your last answer. It totally helps to clear up the problem I had.

Juan Pablo

0 Kudos
Reply