3

以下代码,结合模块程序外部程序

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

似乎失败了:

  1. segmentation fault
  2. 打印一个块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 标准(第 12.3.2.4 节)中发现的内容是:

从过程接口是隐式的作用域单元引用的过程的类型、类型参数和虚拟参数的形状必须使得实际参数与虚拟参数的特征一致。

在这种情况下,该规则似乎得到了尊重,因为a它总是被声明为

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

那么,我在解释使先前代码错误的标准时遗漏了什么?

4

1 回答 1

6

假定形状的虚拟参数必须在其参考点具有显式接口。F90 12.3.1.1 项目 2c。

实际上,假设的形状数组是通过传递一个描述符来传递的——一个描述数组的边界和存储位置的小结构。Ye-olde F77 显式形状和假定大小的数组只需传递第一个元素的地址即可。如果没有显式接口,编译器不知道它需要构建和传递描述符——因此会导致混乱和混乱。

于 2012-11-08T20:52:13.783 回答