英特尔Fortran 95编译器是否允许模块阵列具有非恒定大小?

时间:2015-07-06 22:12:47

标签: arrays fortran gfortran intel-fortran fortran95

我已经下载了Fortran 90/95自适应网状物再生库(Paramesh),现在我正在尝试编译随附的示例程序。在这个过程中,我修改了Makefile以使用gfortran而不是Intel Fortran编译器。

在库代码中,有一个包含此代码段的模块:

       module physicaldata

! Many many lines of variable definitions here
!....
       Public :: nfluxvar
       Integer,Save :: nfluxvar

! Many many lines of variable definitions here
!....

       end module physicaldata

其他地方有

       module flux_assign
        use physicaldata
        integer :: iflux_target(nfluxvar)
       end module flux_assign

导致this error

advance_soln_vdt.F90:16.40:
    Included at amr_main_prog.F90:29:

       integer :: iflux_target(nfluxvar)
                                    1
Error: The module or main program array 'iflux_target' at (1) must have constant shape

如果使用其他编译器编译,该代码是否有效?我知道使用标准的Fortran,或者至少是gfortran使用的Fortran,要求用于表示数组大小的整数变量应该附加parameter关键字。其他Fortran编译器不是这样吗?其他编译器是否包含非标准功能,例如?

3 个答案:

答案 0 :(得分:3)

当前的英特尔Fortran会为此代码发出错误。

标准语言要求在模块的规范部分(或主程序或块数据或子模块以及在其他一些地方使用的数组)中声明的不可分配的非指针数组必须具有常量数组边界。 / p>

iflux_target就是这样一个数组。

具有此类阵列的程序不符合要求,如果没有符合标准的Fortran处理器的诊断,则不会接受该程序。如果可移植性是您的目标,那么请不要使用此类功能。以前版本的英特尔Fortran缺乏诊断可能是一种疏忽。

需要使变量由变量指定的模块数组应该是可分配的,并且数组在"初始化"中分配。在使用模块提供的操作之前的程序或类似程序。

答案 1 :(得分:2)

用于指定静态分配数组的整数不能在fortran中具有save属性,因为这意味着它将在运行期间更改(否则为什么使用save)。由于数组是静态分配的,因此其边界不能更改。查看this答案了解更多详情。

这也标志着intel编译器上的以下错误,

An automatic object must not appear in the specification part of a module

请注意,指定nfluxvar的值,例如

integer :: nfluxvar=5

并不意味着您可以使用它来定义数组大小,除非您明确告诉编译器它是parameter

如果使用动态分配的数组,则无需对数组大小parameter使用nfluxvar语句。如果要避免此问题,使用动态分配是最佳解决方案,因为它将数组大小显式设置为当前值nfluxvar。如果更改,您甚至可以重新分配,例如

module physicaldata

    ! Many many lines of variable definitions here
    !....
    Public :: nfluxvar
    Integer,Save :: nfluxvar

    ! Many many lines of variable definitions here
    !....

end module physicaldata




module flux_assign
    use physicaldata

    integer, allocatable, dimension(:) :: iflux_target

end module flux_assign


program main
    use flux_assign

    if (.not. allocated(iflux_target)) then
        allocate(iflux_target(nfluxvar))
    elseif (size(iflux_target) .ne. nfluxvar) then
        deallocate(iflux_target)
        allocate(iflux_target(nfluxvar)) 
    endif


end program main

答案 2 :(得分:1)

在某种程度上,这不是一个真正的答案。但是,任何兼容的Fortran编译器都必须能够检测并报告Fortran语言规范中指定约束的违规。您在代码中遇到的约束确实是其中之一。那么,是否存在Fortran编译器,它能够检测到这一点,但却选择不这样做?我不知道。但我不这么认为。

那么,约束是什么?除非nfluxvar是常量表达式,iflux_target将是自动对象。模块的作用域单元中不允许使用这样的自动对象 - 请参阅Fortran 2008中的C554和周围文本。

要回答标题中的问题:ifort将大声抱怨此类尝试。