以下代码,结合模块程序和外部程序:
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
似乎也失败了:
segmentation fault
0.000
块而不是1.000
到目前为止我尝试过的任何平台上。该问题与bar
的隐式接口声明有关,实际上可以通过任何方式添加显式接口来解决问题,例如使用:
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
或在bar
使用的模块中声明module_dummy
。
无论如何我真的不明白首先是什么错误。我在Fortran 90 standard上发现的内容(第12.3.2.4节)说:
过程的伪参数的类型,类型参数和形状 从过程接口所在的作用域单元引用 隐式必须是这样的,实际的参数是一致的 伪论证的特征。
在这种情况下,规则似乎得到尊重,因为a
始终声明为
real, intent(inout) :: a(:)
那么,在解释使前一个代码错误的标准时我缺少什么?
答案 0 :(得分:4)
假定形状的虚拟参数必须在其参考点具有显式接口。 F90 12.3.1.1项目2c。
实际上,通过传递描述符来传递假定的形状数组 - 描述数组存储的边界和位置的一个小结构。只需传递第一个元素的地址即可传递Ye-olde F77显式形状和假定大小数组。如果没有显式接口,编译器就不会知道它需要构建并传递描述符 - 因此会产生混乱和混乱。