procedure pointer with implicit interface problem

procedure pointer with implicit interface problem

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

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 

*compiled with ifort 13.0.1 under linux mint 14

5 帖子 / 0 全新
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项
Steve Lionel (Intel)的头像

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.

Steve

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?

 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 
 

*compiled with ifort 13.0.1 under linux mint 14

Steve Lionel (Intel)的头像

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:

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

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?

Steve

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

Juan Pablo

登陆并发表评论。