将未分配的可分配变量作为可分配的虚拟参数传递 [英] Passing unallocated allocatable variable as an allocatable dummy argument

查看:55
本文介绍了将未分配的可分配变量作为可分配的虚拟参数传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的程序中,一个可分配的变量x被传递给子程序test_sub而没有被分配.在test_sub中分配对应的可分配虚拟变量x_sub:

In the following program, an allocatable variable x is passed to a subroutine test_sub without being allocated. The corresponding allocatable dummy variable x_sub is allocated in 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:

When control is returned to the main program, x is allocated:

 Before call to sub F
 After call to sub T

如果test_sub在分配x_sub前返回,或者x_sub在返回前被释放,则x不被分配:

If test_sub returns before allocating x_sub, or if x_sub is deallocated before returning, x is not allocated:

 Before call to sub F
 After call to sub F

我使用 gfortran 4.4.7 和 ifort 19.0 观察到这种行为.

I observe this behavior using both gfortran 4.4.7 and ifort 19.0.

我的问题是这是否是标准行为.我本来希望在尝试传递 x 而不分配它时会出现段错误.我担心这种行为可能会导致大型程序出现意外结果.

My question is whether this is standard behavior. I would have expected to get a segfault when trying to pass x without it being allocated. I'm worried this behavior might lead to unexpected results in larger programs.

推荐答案

您可以使用 intent 声明来控制例程中变量的分配行为:

You can use an intent declaration to control the allocation behavior of your variable inside the routine:

  1. real, allocatable, intent(inout) :: x(:) 等价于你的情况.

  • 分配状态不是先验的,可以用allocated(x)进行测试;
  • 分配状态可以使用allocate/deallocate
  • 改变
  • Allocation status is not known a priori, it can be tested with allocated(x);
  • Allocation status can change using allocate/deallocate

如果real, allocatable,intent(in) :: x(:),则分配状态不能在里面改变;

if real, allocatable, intent(in) :: x(:), then the allocation status cannot change inside of it;

  • 可以使用 allocated(x)
  • 测试分配状态
  • 无法修改

如果 real, allocatable,intent(out) :: x(:),那么变量 x 总是初始化为非分配,不管它是什么调用例程之前的状态,因此您可以总是allocate(x(n)) 开始您的子例程.

if real, allocatable, intent(out) :: x(:), then variable x is always initialized as non-allocated, regardless of its former status before calling the routine, so you can always begin your subroutine with allocate(x(n)).

我相信您正在使用选项 1),但您想要 3).

I believe you're using option 1) but you want 3).

这篇关于将未分配的可分配变量作为可分配的虚拟参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆