模块或主程序数组在 Fortran 中必须具有常量形状错误

Module or main program array must have constant shape error in Fortran

在模块中声明的整型变量作为全局变量来定义程序中相关数组的大小。程序的大小各不相同,所以数组的大小是一个变量而不是一个参数。它是在程序开始时确定的。

在下面的代码片段中,n 是全局大小变量。它在模块中声明,定义在mainfunction/program的开头。主程序中n的用法类似,主程序中包含的子程序分别初始化一个数组。但是,主程序中的初始化导致错误:模块或主程序数组必须具有常量形状错误,但子程序中的初始化有效。这种对不同位置使用的非常量值的不同处理背后的机制是什么?

module mod
  implicit none
  integer :: n
end module mod



program main
  use mod
  implicit none
  integer :: b(n)
  n = 5
  b(:) = 1
  print*, b(:)

  call sub

contains

  subroutine sub
    integer :: a(n)
    a = 10
    print*, a
  end subroutine sub

end program main

a(n) 这样声明的数组是一个 明确形状 数组。当 n 不是常量(命名或其他方式,严格来说是常量表达式)时,这样的数组是 自动对象 .

自动对象的出现位置受到限制。特别是,显式形状数组受以下约束(F2008 的 C531):

An explicit-shape-spec whose bounds are not constant expressions shall appear only in a subprogram, derived type definition, BLOCK construct, or interface body.

由于模块 mod 中的 n 不是常量,因此不能用作主程序中数组的边界。子例程 sub 是一个子程序,因此 a(n) 是对非常量边界的有效使用。

我们可以考虑 延迟形状 数组,而不是在主程序中使用自动对象,使用 pointerallocatable 属性。