将未分配的可分配变量作为可分配的虚拟参数传递
Passing unallocated allocatable variable as an allocatable dummy argument
在下面的程序中,一个可分配变量 x
被传递给一个子程序 test_sub
而没有被分配。相应的可分配虚拟变量 x_sub
分配在 test_sub
:
module test_mod
implicit none
contains
subroutine test_sub(x_sub)
implicit none
real, allocatable :: x_sub(:)
! Execution !
! return
allocate(x_sub(1))
! deallocate(x_sub)
end subroutine test_sub
end module test_mod
program test
use test_mod, only: test_sub
implicit none
real, allocatable :: x(:)
! Execution !
print*, 'Before call to sub', allocated(x)
call test_sub(x)
print*, 'After call to sub', allocated(x)
end program test
当控制返回到主程序时,分配x
:
Before call to sub F
After call to sub T
如果test_sub
returns在分配x_sub
之前,或者如果x_sub
在返回之前被释放,则x
不分配:
Before call to sub F
After call to sub F
我使用 gfortran 4.4.7 和 ifort 19.0 观察到这种行为。
我的问题是这是否是标准行为。我本以为在尝试传递 x
而不分配它时会出现段错误。我担心这种行为可能会导致大型程序出现意外结果。
这是标准行为。 allocatable
的虚拟参数 没有暗示需要在输入或输出上分配变量 。这只是意味着该变量是可分配的,因此您可以将其视为该函数内部的可分配变量,例如隐式重新分配等。
要查明它是否是自动分配的,您应该在执行自己的 allocate
之前在子例程中打印它。没有进行自动分配。
将未分配的可分配对象传递给可分配的虚拟参数是完全没问题的。它作为“未分配”传递。
您可以使用 intent
声明来控制例程中变量的分配行为:
real, allocatable, intent(inout) :: x(:)
等同于你的情况。
- 分配状态先验未知,可以使用
allocated(x)
; 进行测试
- 分配状态可以使用
allocate
/deallocate
更改
如果real, allocatable, intent(in) :: x(:)
,则分配状态不能在里面改变;
- 可以使用
allocated(x)
测试分配状态
- 无法修改
如果 real, allocatable, intent(out) :: x(:)
,那么变量 x 总是 初始化为未分配的 ,无论它在调用例程之前的状态如何,所以你总是可以用allocate(x(n))
开始你的子程序吗?
我相信您使用的是选项 1),但您想要选项 3)。
在下面的程序中,一个可分配变量 x
被传递给一个子程序 test_sub
而没有被分配。相应的可分配虚拟变量 x_sub
分配在 test_sub
:
module test_mod
implicit none
contains
subroutine test_sub(x_sub)
implicit none
real, allocatable :: x_sub(:)
! Execution !
! return
allocate(x_sub(1))
! deallocate(x_sub)
end subroutine test_sub
end module test_mod
program test
use test_mod, only: test_sub
implicit none
real, allocatable :: x(:)
! Execution !
print*, 'Before call to sub', allocated(x)
call test_sub(x)
print*, 'After call to sub', allocated(x)
end program test
当控制返回到主程序时,分配x
:
Before call to sub F
After call to sub T
如果test_sub
returns在分配x_sub
之前,或者如果x_sub
在返回之前被释放,则x
不分配:
Before call to sub F
After call to sub F
我使用 gfortran 4.4.7 和 ifort 19.0 观察到这种行为。
我的问题是这是否是标准行为。我本以为在尝试传递 x
而不分配它时会出现段错误。我担心这种行为可能会导致大型程序出现意外结果。
这是标准行为。 allocatable
的虚拟参数 没有暗示需要在输入或输出上分配变量 。这只是意味着该变量是可分配的,因此您可以将其视为该函数内部的可分配变量,例如隐式重新分配等。
要查明它是否是自动分配的,您应该在执行自己的 allocate
之前在子例程中打印它。没有进行自动分配。
将未分配的可分配对象传递给可分配的虚拟参数是完全没问题的。它作为“未分配”传递。
您可以使用 intent
声明来控制例程中变量的分配行为:
real, allocatable, intent(inout) :: x(:)
等同于你的情况。- 分配状态先验未知,可以使用
allocated(x)
; 进行测试
- 分配状态可以使用
allocate
/deallocate
更改
- 分配状态先验未知,可以使用
如果
real, allocatable, intent(in) :: x(:)
,则分配状态不能在里面改变;- 可以使用
allocated(x)
测试分配状态
- 无法修改
- 可以使用
如果
real, allocatable, intent(out) :: x(:)
,那么变量 x 总是 初始化为未分配的 ,无论它在调用例程之前的状态如何,所以你总是可以用allocate(x(n))
开始你的子程序吗?
我相信您使用的是选项 1),但您想要选项 3)。