- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have some code that worked in v11, but is giving me an "unhandled exception" with v12, Update 3. I have a procedure pointer in a module header. I then have a routine that is used to set the routine which is pointed to.
A simplified example follows. Is this illegal code, or is there a compiler bug?
A simplified example follows. Is this illegal code, or is there a compiler bug?
[fortran]module my_module implicit none procedure(routine_interface),pointer :: my_routine => null() abstract interface subroutine routine_interface(str) implicit none character(len=*),intent(in) :: str end subroutine routine_interface end interface contains subroutine set_routine !sets the my_routine proc pointer implicit none procedure(routine_interface),pointer :: r my_routine => r end subroutine set_routine subroutine call_routine(str) !calls the routine pointed to by my_routine implicit none character(len=*),intent(in) :: str call my_routine(str) !<--------------------unhandled exception!!! end subroutine call_routine subroutine routine1(str) implicit none character(len=*),intent(in) :: str write(*,*) trim(str) end subroutine routine1 end module my_module program main use my_module call set_routine(routine1) !doesn't work !my_routine => routine1 !works call call_routine('hello') end program main[/fortran]
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The IFort 12.0.2 compiler gives no warning/error when run with /gen-interfaces /warn:interfaces.
I suspect, however, that the following may cause problems. Line 38 calls set_routine with a procedure as the argument, but the declaration of set_routine requires it to be given a procedure pointer.
Pointers in Fortran behave differently than in, say, C. You could try modifying the program to make the formal and actual argument types match.
I suspect, however, that the following may cause problems. Line 38 calls set_routine with a procedure as the argument, but the declaration of set_routine requires it to be given a procedure pointer.
Pointers in Fortran behave differently than in, say, C. You could try modifying the program to make the formal and actual argument types match.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, if I change to main program to:
It works. It seems cumbersome to me, though. Is this the way it has to be done? My original code worked with v11 of the compiler (was that a bug in the earlier version allowing it to work?) The basic idea is I want a procedure pointer that is private to a module, that can only be changed via a subroutine call.
Thanks for the help!
[fortran]program main use my_module procedure(routine_interface),pointer :: tmp => null() tmp => routine1 call set_routine(tmp) call call_routine('hello') end program main[/fortran]
It works. It seems cumbersome to me, though. Is this the way it has to be done? My original code worked with v11 of the compiler (was that a bug in the earlier version allowing it to work?) The basic idea is I want a procedure pointer that is private to a module, that can only be changed via a subroutine call.
Thanks for the help!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the original code, all I have to do is change:
[fortran]procedure(routine_interface),pointer :: r [/fortran]to:
[fortran]procedure(routine_interface) :: r [/fortran]and it works.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
At first I thought the original code was not legal Fortran and that the error was that the compiler failed to diagnose it. (/warn:interface would not be useful here as there is an explicit interface already.) Well, the code is illegal, but not for the reason I thought. The standard says (emphasis mine):
If a dummy argument is a procedure pointer, the corresponding actual argument shall be a procedure pointer, a
reference to a function that returns a procedure pointer, a reference to the intrinsic function NULL, or a valid
target for the dummy pointer in a pointer assignment statement. If the actual argument is not a pointer, the
dummy argument shall have the INTENT (IN) and becomes pointer associated with the actual argument.
So the error is that INTENT(IN) was missing and the compiler should have caught that. Well, yes, that's an error, but even adding INTENT(IN) doesn't solve the problem, as the compiler is failing to turn this into pointer association. I have reported both of these to development - the issue ID is DPD200168295.
If a dummy argument is a procedure pointer, the corresponding actual argument shall be a procedure pointer, a
reference to a function that returns a procedure pointer, a reference to the intrinsic function NULL, or a valid
target for the dummy pointer in a pointer assignment statement. If the actual argument is not a pointer, the
dummy argument shall have the INTENT (IN) and becomes pointer associated with the actual argument.
So the error is that INTENT(IN) was missing and the compiler should have caught that. Well, yes, that's an error, but even adding INTENT(IN) doesn't solve the problem, as the compiler is failing to turn this into pointer association. I have reported both of these to development - the issue ID is DPD200168295.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is a feature that is new in Fortran 2008 and is not yet supported. It will be fixed in a future release.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page