'Module calling an external procedure with implicit interface

The following code, combining module procedures and external procedures:

module module_dummy

  implicit none

contains

  subroutine foo(a)

    real, intent(inout) :: a(:)

    call bar(a)

  end subroutine foo

end module module_dummy

program main

  use module_dummy

  implicit none 

  integer, parameter :: nelems = 100000000
  real,  allocatable :: a(:)

  allocate( a(nelems) )
  a = 0.0
  call foo(a)
  print *, a(1:10)
  deallocate(a)

end program main

subroutine bar(a)

  implicit none

  real, intent(inout) :: a(:)

  a = 1.0      

end subroutine bar

seems to fail either:

  1. with a segmentation fault
  2. printing a block of 0.000 instead of a block of 1.000

on any platform I have tried so far. The problem is related to the implicit interface declaration of bar, and in fact the issue can be solved adding in any way an explicit interface, e.g. using:

module module_dummy

  implicit none

contains

  subroutine foo(a)

    interface 
       subroutine bar(x)
         real, intent(inout) :: x(:)
       end subroutine bar
    end interface

    real, intent(inout) :: a(:)

    call bar(a)

  end subroutine foo

end module module_dummy

or declaring bar inside a module to be used by module_dummy.

Anyhow I really don't understand what is the error in the first place. What I have found on the Fortran 90 standard (sec. 12.3.2.4) says that:

The type, type parameters, and shape of dummy arguments of a procedure referenced from a scoping unit where the interface of the procedure is implicit must be such that the actual arguments are consistent with the characteristics of the dummy arguments.

In this case the rule seems to be respected, as a is always declared as

real, intent(inout) :: a(:) 

So, what am I missing in the interpretation of the standard that makes the previous code wrong?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source