将非连续参数传递给 Fortran 过程中的连续虚拟数组
Passing non-contiguous argument to contiguous dummy array in a Fortran procecdue
最近我在处理具有 contiguous
属性的虚拟数组的子例程时遇到了 Fujitsu Fortran 版本 2.0.0 的意外行为。
我已将问题简化为此处的一个简单示例:
program test
INTEGER, DIMENSION(:,:), ALLOCATABLE :: t
INTEGER :: i, j
ALLOCATE(t(3,3))
DO i = 1, 4
DO j = 1, 4
t(i,j) = i*j
!!PRINT *, t(i,j)
END DO
END DO
CALL fun(t(2,1:4:2))
DEALLOCATE(t)
CONTAINS
SUBROUTINE fun(arg)
! Contiguous dummy argument arg
INTEGER, CONTIGUOUS :: arg(:)
PRINT *, arg(2)
END SUBROUTINE
end program test
这段代码可以通过 gfortran (GNU Fortran (GCC) 6.3.0) 成功编译,但在使用 Fujitsu Fortran 编译器(如上所述)的集群上失败,给出以下错误代码:
"test_contiguous.f90", line 13: The actual argument number 1 of procedure 'fun' corresponding to a dummy argument 'arg' with the CONTIGUOUS attribute must be contiguous.
我很困惑,因为据我所知,编译器应该在子例程的入口处创建一个连续的临时文件(如示例所示:Fortran 2008 contiguous)
其实我有两个问题:
- 这种情况的规范是什么?
- 它可以是编译器的标志,迫使他为这种情况创建一个连续的临时文件吗?
我正在尝试构建第三方软件,无法随意更改源。
Fortran 2008 规范说明 (5.3.7) 具有 contiguous
属性的假定形状虚拟参数:
The CONTIGUOUS attribute specifies that an assumed-shape array can only be argument associated with a contiguous effective argument, or that an array pointer can only be pointer associated with a contiguous target.
另一方面,Fortran 2018 规范说 (8.5.7):
The CONTIGUOUS attribute specifes that an assumed-shape array is contiguous, that an array pointer can only be pointer associated with a contiguous target, or that an assumed-rank dummy data object is contiguous.
可以看出,一个限制有效参数(本例t(2,1:4:2)
主程序),另一个不限制。
不过需要注意的是,这里的限制是对程序的限制,不需要编译器detect/enforce。即使在 Fortran 2008 模式下,编译器也可以自由地接受不连续的参数,制作临时副本。在这两种情况下,都必须编译器制作临时副本。
至于某个特定的编译器是否有放宽其假设的选项,在这种情况下我不能说:我无法访问这个来测试。我很高兴有人编辑这个答案,应该找到这样一个选项。
最近我在处理具有 contiguous
属性的虚拟数组的子例程时遇到了 Fujitsu Fortran 版本 2.0.0 的意外行为。
我已将问题简化为此处的一个简单示例:
program test
INTEGER, DIMENSION(:,:), ALLOCATABLE :: t
INTEGER :: i, j
ALLOCATE(t(3,3))
DO i = 1, 4
DO j = 1, 4
t(i,j) = i*j
!!PRINT *, t(i,j)
END DO
END DO
CALL fun(t(2,1:4:2))
DEALLOCATE(t)
CONTAINS
SUBROUTINE fun(arg)
! Contiguous dummy argument arg
INTEGER, CONTIGUOUS :: arg(:)
PRINT *, arg(2)
END SUBROUTINE
end program test
这段代码可以通过 gfortran (GNU Fortran (GCC) 6.3.0) 成功编译,但在使用 Fujitsu Fortran 编译器(如上所述)的集群上失败,给出以下错误代码:
"test_contiguous.f90", line 13: The actual argument number 1 of procedure 'fun' corresponding to a dummy argument 'arg' with the CONTIGUOUS attribute must be contiguous.
我很困惑,因为据我所知,编译器应该在子例程的入口处创建一个连续的临时文件(如示例所示:Fortran 2008 contiguous)
其实我有两个问题:
- 这种情况的规范是什么?
- 它可以是编译器的标志,迫使他为这种情况创建一个连续的临时文件吗?
我正在尝试构建第三方软件,无法随意更改源。
Fortran 2008 规范说明 (5.3.7) 具有 contiguous
属性的假定形状虚拟参数:
The CONTIGUOUS attribute specifies that an assumed-shape array can only be argument associated with a contiguous effective argument, or that an array pointer can only be pointer associated with a contiguous target.
另一方面,Fortran 2018 规范说 (8.5.7):
The CONTIGUOUS attribute specifes that an assumed-shape array is contiguous, that an array pointer can only be pointer associated with a contiguous target, or that an assumed-rank dummy data object is contiguous.
可以看出,一个限制有效参数(本例t(2,1:4:2)
主程序),另一个不限制。
不过需要注意的是,这里的限制是对程序的限制,不需要编译器detect/enforce。即使在 Fortran 2008 模式下,编译器也可以自由地接受不连续的参数,制作临时副本。在这两种情况下,都必须编译器制作临时副本。
至于某个特定的编译器是否有放宽其假设的选项,在这种情况下我不能说:我无法访问这个来测试。我很高兴有人编辑这个答案,应该找到这样一个选项。