Fortran函数指定输入和输出数组的大小以及gfortran边界检查

时间:2015-07-15 20:05:52

标签: arrays function fortran

我们假设我有以下的fortran程序

~/.hgrc

如果我用

编译这段代码
program foobar
implicit none

interface
    pure function foo (var1, var2) result(ans)
        implicit none
        integer, dimension(:),          intent(in) :: var1
        integer, dimension(size(var1)), intent(in) :: var2
        integer, dimension(product(var1 + var2)) :: ans
    end function foo

    pure function bar (n, var1, var2) result(ans)
         implicit none
         integer,                        intent(in) :: n
         integer, dimension(:),          intent(in) :: var1
         integer, dimension(size(var1)), intent(in) :: var2
         integer, dimension(n)                      :: ans
   end function bar
end interface

write (*,*) foo([1, 1, 1], [2, 2, 2])
! write (*,*) bar(27, [1, 1, 1], [2, 2, 2])   
end program foobar

pure function foo (var1, var2) result(ans)
     implicit none
     integer, dimension(:),          intent(in) :: var1
     integer, dimension(size(var1)), intent(in) :: var2
     integer, dimension(product(var1 + var2))   :: ans
     ans = 0
end function foo

pure function bar (n, var1, var2) result(ans)
     implicit none
     integer,                        intent(in) :: n
     integer, dimension(:),          intent(in) :: var1
     integer, dimension(size(var1)), intent(in) :: var2
     integer, dimension(n) :: ans
     ans = 0
end function bar

然后我在执行期间收到以下错误

  

Fortran运行时错误:数组的维度1的数组绑定不匹配' var2' (0/3)

如果省略-fcheck = all选项,代码编译并运行就好了。如果我在主程序中注释第一次写入并取消注释第二次写入,则代码编译并运行正常,无论我是否使用-fcheck = all选项。我无法与其他编译器核实,因为gfortran是我目前唯一可以访问的编译器。

据我所知,编译器无法确定数组的大小,因此在运行时检查失败。这种解释是否正确?其次,是否有一些规则可以放在维度()声明中,这样编译器仍然可以在运行时进行一些边界检查?我应该总是明确传递数组的大小吗?这样我就可以解决这些问题,但这会使调用这些函数变得非常繁琐。

2 个答案:

答案 0 :(得分:1)

这是一个编译器错误,已在最新版本中修复。在我的计算机上,它失败了gfortran 4.7。并且在预先发布gfortran-5时运行正常。

答案 1 :(得分:1)

首先,回答结果变量dimension的{​​{1}}声明中的内容。

ans是一个显式形状数组,因此您提供的绑定必须是规范表达式。因为它是一个结果变量,所以它不需要是一个常量表达式,只是一个受限制的表达式。有关如何组成受限表达式的详细信息,请参见Fortran 2008 7.1.11。

让我们看看构成表达式ans的事物。如果这是一个受限制的表达方式,那么您可以按原样使用它。

product(var1 + var2)var1是没有var2intent(out)属性的虚拟变量。这很好。下一步是什么?

optional这是内在的操作。蜱。将+限制为表达式。

var1+var2是一个标准的内在函数,它不是一个规范查询函数,它的参数是一个受限制的表达式,在这种情况下它的结果是一个标量整数epxression。

所以,所有这一切都说:没关系。

而且,正如Vladimir F所说:它是一个编译器错误。这只是证实它不是程序员的错误。