具有意图(在)参数的fortran参数的初始化



考虑以下程序:

Subroutine foo(p,v)
  implicit none
  integer,                         intent(in)  :: p
  double precision,  dimension(p), intent(in)  :: v 
  !local variables
  integer,parameter :: n=floor(par(p))
  double precision  :: z(2*n)
[...]
End Subroutine

我有以下错误:

Error: Array ‘v’ at (1) is a variable, which does not reduce to a constant expression

哪个非常明确,但我想知道是否有一种管理这种情况的方法:将子例程的intent(in)参数分配给参数变量?

不,这是不可能的。参数为A 编译时常数。它的价值不能来自任何参数或变量。

也不清楚为什么要这样做(请参阅https://meta.stackexchange.com/questions/66377/what-is-the--xy-problem)。您做不是需要一个参数来声明数组

double precision :: z(2*floor(par(p)))

因为在自动阵列中界限可以是过程参数。

您可以使用零长度变量保存可以通过规范查询从中提取的中间结果。示例的时间:

module mod_par
   implicit none
   contains
      pure function par(x)
         double precision par
         integer, intent(in) :: x
         par = 1+sqrt(real(1,kind(par))+x)
      end function par
end module mod_par
module mod_foo
!   use mod_par
   implicit none
   double precision par
   contains
      subroutine foo(p,v)
         implicit none
         integer p
         double precision v
         character(0) sv_i(floor(par(p)))
         character(floor(par(p))) sv_j(0)
         logical sv_k(floor(par(p)),0)
         type t
         ! Intentionally empty
         end type t
         type(t) sv_L(floor(par(p)))
         type u(len)
            integer, len :: len
         ! intentionally empty
         end type u
         type(u(floor(par(p)))) sv_m
         double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),sv_m%len,0)
!         double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),0)
         write(*,*) shape(z)
      end subroutine foo
end module mod_foo
program bar
   use mod_par
   use mod_foo
   implicit none
   call foo(10,1.0d0)
end program bar

这在IFORT和GFORTRAN上都失败了,因为规范功能(此处为par)必须为PURE,并且其接口必须显式。在这里par,尽管PURE具有隐式接口,因此被拒绝。实际上,两个编译器似乎都感到困惑:

specvar.f90:21:25:
          character(floor(par(p))) sv_j(0)
                         1
Error: Function 'par' at (1) has no IMPLICIT type

gfortran和ifort说

specvar.f90(31): error #6404: This name does not have a type, and must have an e
xplicit type.   [PAR]
         type(u(floor(par(p)))) sv_m
----------------------^

所以我们修复了此编程错误...

module mod_par
   implicit none
   contains
      pure function par(x)
         double precision par
         integer, intent(in) :: x
         par = 1+sqrt(real(1,kind(par))+x)
      end function par
end module mod_par
module mod_foo
   use mod_par
   implicit none
!   double precision par
   contains
      subroutine foo(p,v)
         implicit none
         integer p
         double precision v
         character(0) sv_i(floor(par(p)))
         character(floor(par(p))) sv_j(0)
         logical sv_k(floor(par(p)),0)
         type t
         ! Intentionally empty
         end type t
         type(t) sv_L(floor(par(p)))
         type u(len)
            integer, len :: len
         ! intentionally empty
         end type u
         type(u(floor(par(p)))) sv_m
         double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),sv_m%len,0)
!         double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),0)
         write(*,*) shape(z)
      end subroutine foo
end module mod_foo
program bar
   use mod_par
   use mod_foo
   implicit none
   call foo(10,1.0d0)
end program bar

但是现在Gfortran说

specvar.f90:32:73:
          double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),sv_m%l
en,0)
                                                                         1
Error: Variable 'sv_m' cannot appear in the expression at (1)

和ifort:

specvar.f90(31): error #6279: A specification expression object must be a dummy
argument, a COMMON block object, or an object accessible through host or use ass
ociation.   [SV_M]
         type(u(floor(par(p)))) sv_m
--------------------------------^

因此,我没有足够的最新版本的任何一个编译器来支持类型的参数查询。bummer。所以我们摆脱了最后一点...

module mod_par
   implicit none
   contains
      pure function par(x)
         double precision par
         integer, intent(in) :: x
         par = 1+sqrt(real(1,kind(par))+x)
      end function par
end module mod_par
module mod_foo
   use mod_par
   implicit none
!   double precision par
   contains
      subroutine foo(p,v)
         implicit none
         integer p
         double precision v
         character(0) sv_i(floor(par(p)))
         character(floor(par(p))) sv_j(0)
         logical sv_k(floor(par(p)),0)
         type t
         ! Intentionally empty
         end type t
         type(t) sv_L(floor(par(p)))
         type u(len)
            integer, len :: len
         ! intentionally empty
         end type u
         type(u(floor(par(p)))) sv_m
!         double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),sv_m%len,0)
         double precision z(size(sv_i),len(sv_j),size(sv_k,1),size(sv_L),0)
         write(*,*) shape(z)
      end subroutine foo
end module mod_foo
program bar
   use mod_par
   use mod_foo
   implicit none
   call foo(10,1.0d0)
end program bar

现在两个编译器都会产生良好的代码。因此,您可以看到,有多种方法可以在零长度自动变量的规格中保存临时整数变量,这些变量可用于进一步的规范表达式。请注意,如果您对这种语法太喜欢,您将经常崩溃编译器。

最新更新