module mms !*************** !some code !*************** procedure(template_get_rho ), pointer :: get_rho => null() interface function template_get_rho(x1, x2, time) result(rho) import :: dp implicit none real(dp), intent(in) :: time real(dp), dimension(0:), intent(in) :: x1, x2 real(dp), allocatable, dimension(:,:) :: rho end function end interface !*************** !some code !*************** contains subroutine initialize_mms select case(mms_case) case(1) !*************** !some code, get_rho is NOT associated to anything !*************** case(2) get_rho => prob2_get_rho end select !nullify(get_rho) <------------------------ Error here when uncommented !get_rho => null() <-------- No errors here if(associated(get_rho)) then <------------------ Error here when get_rho set to null() rho(0:nx-1, 0:ny-1) = get_rho(x, y, time) end if end subroutine !************ ! some code !************ end module mms
You are missing some code from your snip.
Line 22, presumably mms_case is a module integer variable not shown
Line 34, we do not know what rho is. Can we assume it is a "procedure(template_get_rho), pointer"? if so, then use => for assignment.
- I have not included all the code as it is too long.
- mms_case is actually a global variable passed by a use statement.
- I made an error while copy-pasting my code here, the assignement was indeed =>
- rho is a 2D array. get_rho points to a function returning just that.
If your minimum example doesn't exhibit the problem, then that suggests that stuff that you have elided from the minimum example is problematic. Perhaps the the elided stuff is trampling memory that causes problems with the pointer assignment.
What is the ifort version? Is it the latest release?
If rho is a data object (a 2D array), then you can't point it at a procedure. Are you missing parentheses after get_rho on line 34?
I agree that the error might actually be somewhere else since I was not able to reproduce the error.
As I've mentioned, I'm using mpiifort 4.1.3.048 but I'm not sure what the latest is. I'm in a university and I think the sys admins only update compiler versions once or twice a year.
About rho, that was (yet again, I apologize) another typo. I have fixed it in an edit. However, the error persists even if I remove that the function call and replace it with, say, a print statement.
I think you have missed the point. The error is before I call get_rho but when it is null() and I check if it is associated. For you info, rho is set with allocate(rho(-buf:nx-1+buf, -buf:ny-1+buf) so there's no problems there. Also, when get_rho is associated, the code runs normally.
I have edited the post so it is more clear.
Earlier I posted what is below the ----
It is strange that nullify(get_rho) fails, but that get_rho => null() succeeds. This somewhat confuses what is stated below.
Do a little introspection: For nullify(get_rho) to fail implies that the memory location of the pointer is invalid. This can happen on Linux if your module is:
a) compiled as a static object (absence of -fpic) as opposed to being position independent (presence of -fpic) .AND. is assembled into a shared library (.so) which requires -fpic.
b) compiled as a position independent object (presence of -fpic) as opposed to a static object (absence of -fpic) .AND. is assembled into a static library (.a) or directly into the executable which both require absence of -fpic.
>>For you info, rho is set with allocate(rho(-buf:nx-1+buf, -buf:ny-1+buf) so there's no problems there.
This is still not entirely clear.
Your interface of get_rho of type template_get_rho has a return array named rho.
The module mms is shown with a procedure pointer get_rho.
The module, as shown, does not contain a module scoped array named rho
IOW the rho specified in initialize_mms cannot possibly be the same rho as specified in you code snip.
Lack of stating where the initialize_mms scoped rho is located, and allocated is not providing us readers with sufficient information to fully understand the environment of the code shown. So this lack of detail makes it difficult for us readers to provide you with anything other than a guess at the usual suspects of the problem.
This is another unfounded guess at the potential problem
Your interface to get_rho (template_get_rho) has the return argument rho attributed as allocatable with no intent. This implies that the procedure (function) pointed to by get_rho is permitted to allocate and/or reallocate and/or deallocate the return array. Also note that the left side of
lhs = get_rho(x, y, time)
can potentially be a pointer to a 2D array of dimension (:,:) in addition to an allocatable array of dimension (:,:).
Therefore there is a potential for some ambiguity as to if the associated(get_rho) applies to the (potential) pointer to the function or the return of the function. I think it should be the pointer to the function and that it may be a compiler bug. However, consider what is to be expected when such a function returns a pointer. Which would the associated(p) refer to??
Now then, IIF (if and only if) all the functions of template_get_rho type will never allocate or reallocate or delete the output array then remove the ", allocatable" from the interface block, and from all functions declared to be used to have its address inserted into the pointer. Doing this will remove the ambiguity from consideration by the compiler.