【问题标题】:Passing unallocated allocatable variable as an allocatable dummy argument将未分配的可分配变量作为可分配的虚拟参数传递
【发布时间】:2020-11-11 09:00:52
【问题描述】:

在下面的程序中,一个可分配变量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在分配x_sub之前返回,或者如果x_sub在返回之前被释放,x不会被分配:

 Before call to sub F
 After call to sub F

我在使用 gfortran 4.4.7 和 ifort 19.0 时都观察到了这种行为。

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

【问题讨论】:

  • 只是一个小提示:您应该更新您的 gfortran 安装。我认为当前版本是 10.2。
  • @jack 不幸的是,这取决于系统管理员。
  • 好吧,我肯定会问他/她,4.4.7 是古老的
  • @DrG 不是,你可以安装自己的GCC。如果您使用 MPI,您可能无法获得正确的互连驱动程序(联系您的管理员),但只需安装更新的 GCC 非常简单。只需在您的主目录中执行此操作即可。我做了很多次。

标签: memory-management fortran


【解决方案1】:

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

  1. real, allocatable, intent(inout) :: x(:) 相当于你的情况。

    • 分配状态未知,可以用allocated(x)测试;
    • 可以使用allocate/deallocate更改分配状态
  2. 如果real, allocatable, intent(in) :: x(:),则分配状态不能在其中改变;

    • 可以使用allocated(x)测试分配状态
    • 不能修改
  3. 如果real, allocatable, intent(out) :: x(:),那么变量 x 总是初始化为未分配,不管它在调用例程之前的先前状态如何,所以你可以总是开始你的子例程allocate(x(n))

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

【讨论】:

    【解决方案2】:

    这是标准行为。 allocatable 的虚拟参数没有暗示需要在输入或输出上分配变量。这只是意味着该变量是可分配的,因此您可以将其视为该函数内部的可分配,例如隐式重新分配等。

    【讨论】:

      【解决方案3】:

      要确定它是否被自动分配,你应该在子程序中打印它,然后再执行你自己的allocate。不会进行自动分配。

      将未分配的可分配对象传递给可分配的虚拟参数是完全可以的。它作为“未分配”传递。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-14
        • 2019-03-28
        相关资源
        最近更新 更多