Fortran子例程的输入参数是否可以在子例程的主体中解除分配和分配? [英] Can a input argument of a Fortran subroutine be deallocated and allocated in the body of the subroutine?

查看:612
本文介绍了Fortran子例程的输入参数是否可以在子例程的主体中解除分配和分配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:我的修改过的代码如下所示:

 程序run_module_test 
使用module_test
隐含无

TYPE(newXYZ),allocatable,intent(inout):: xyzArray(:)

call update(xyzArray)
write(6,*)'xyzArray ',xyzArray

结束程序run_module_test

模块module_test
隐式无

TYPE :: newXYZ
real(4) :: x,u
real(4):: y,v
real(4):: z,w
real(4),dimension(3):: uvw
结束类型

整数(4):: shape = 3

包含

子程序更新(xyzArray)

整数(4):: i
TYPE(newXYZ),可分配,意图(inout):: xyzArray(:)
allocate(xyzArray(shape))

do i = 1,shape
xyzArray(i)%x = 0
xyzArray(i)%y = 0
xyzArray(i)%z = 0
xyzArray(i)%u = 0
xyzArray(i)%v = 0
xyzArray(i)%w = 0
xyzArray(i)%uvw =(/ 0,0,0 /)
结束do
返回
结束子程序更新

end module module_test

当它们被编译时,它们会产生类似的错误:

  TYPE(newXYZ),allocatable,intent(inout):: xyzArray(:) 
1
错误:ALLOCATABLE在(1)

时,与DUMMY属性的属性冲突当我消除update()子例程中的参数时,I收到一个矛盾的错误:

pre $ TYPE(newXYZ),allocatable,intent(inout):: xyzArray(:)
1
错误:(1)的符号不是一个DUMMY变量

在有用的建议中指出错误的来源?这可能是一个编译器相关的错误(使用mpi90)?

~~~首先编辑~~~
我有一个子程序,其输入参数是用户定义类型XYZ的数组。我希望取消分配xyzArray,并在子例程的主体中将其分配/修改为不同的大小。我尝试了在fortran中更改数组维数所建议的方法,但是当我执行以下操作时:

 子程序更新(xyzArray,...)
...
TYPE(XYZ), allocatable :: xyzArray(:)

我收到一条错误消息:

 错误:ALLOCATABLE属性与(1)处的DUMMY属性冲突

当我尝试时:

 子程序更新(xyzArray,...)
.. 。
deallocate(xyzArray(myshape))
allocate(xyzArray(newshape))



<

 错误:(1)处的DEALLOCATE语句中的表达式必须是ALLOCATABLE或POINTER 
错误:(1)处的ALLOCATE语句中的表达式必须是ALLOCATABLE或POINTER

我需要什么要做些改变数组的大小在子程序中?

解决方案

要做到这一点:


  • 伪参数必须是可分配的。可分配的虚拟参数需要一个编译器来实现Fortran 2003标准的相关部分(或者是一个实现所谓的可分配TR的Fortran 95编译器)。

  • >需要一个明确的过程接口(该过程必须是一个模块过程,一个内部过程或者在调用范围内有一个接口块)。 伪参数不能是意图(in)。如果在子例程中根本不使用伪参数值的分配状态或其他方面,那么intent(out)可能是合适的(如果预先分配,在调用过程时将自动释放伪参数),否则意图(inout)或无意。 (您的第二块示例代码在释放语句时出现语法错误 - 您应该简单地指定<$>
    $ b c $ c> xyzArray 变量,离开(myshape)形状规范))



    <例如,在一个模块中:

     子程序更新(xyzArray)
    类型(xyz),可分配,意图(inout):: xyzArray(:)
    ...
    if(allocated(xyzArray))deallocate(xyzArray)
    allocate(xyzArray(newshape))
    ...


    UPDATE: My modified code looks like this:

    program run_module_test
        use module_test
        implicit none   
    
        TYPE(newXYZ), allocatable, intent(inout) :: xyzArray(:)
    
        call update(xyzArray)
        write(6,*)'xyzArray',xyzArray
    
    end program run_module_test
    
    module module_test
        implicit none
    
        TYPE :: newXYZ
            real(4) :: x, u
            real(4) :: y, v
            real(4) :: z, w
            real(4),dimension(3) :: uvw     
        END TYPE
    
        integer(4) :: shape = 3
    
    contains
    
        subroutine update(xyzArray)
    
        integer(4) :: i
        TYPE(newXYZ), allocatable, intent(inout) :: xyzArray(:)
        allocate( xyzArray(shape) ) 
    
        do i = 1, shape
            xyzArray(i)%x = 0
            xyzArray(i)%y = 0
            xyzArray(i)%z = 0
            xyzArray(i)%u = 0
            xyzArray(i)%v = 0
            xyzArray(i)%w = 0
            xyzArray(i)%uvw = (/0,0,0/)
        end do
        return
        end subroutine update
    
    end module module_test
    

    When they are compiled, they generate a similar error:

     TYPE(newXYZ), allocatable, intent(inout) :: xyzArray(:)
                                                        1
    Error: ALLOCATABLE attribute conflicts with DUMMY attribute at (1)
    

    When I eliminate the argument in update() subroutine, I receive a contradictory error:

    TYPE(newXYZ), allocatable, intent(inout) :: xyzArray(:)
                                                           1
    Error: Symbol at (1) is not a DUMMY variable
    

    Have I eliminated the sources of error pointed out in the helpful suggestions? Could this be a compiler related error (using mpi90)?

    ~~~First Edit~~~ I have a subroutine whose input argument is an array of user defined type XYZ. I wish to deallocate xyzArray and allocate/modify it to a different size in the body of the subroutine. I attempted the method suggested by changing array dimensions in fortran, but when I do the following:

    subroutine update(xyzArray, ...)
    ...
    TYPE (XYZ), allocatable :: xyzArray(:)
    

    I receive an error message:

    Error: ALLOCATABLE attribute conflicts with DUMMY attribute at (1)
    

    When I try:

    subroutine update(xyzArray, ...)
    ...
    deallocate( xyzArray(myshape) )
    allocate( xyzArray(newshape) )
    

    I receive error messages:

    Error: Expression in DEALLOCATE statement at (1) must be ALLOCATABLE or a POINTER
    Error: Expression in ALLOCATE statement at (1) must be ALLOCATABLE or a POINTER
    

    What do I need to do to change the size of the array in the subroutine?

    解决方案

    To do this:

    • The dummy argument must be allocatable. Allocatable dummy arguments require a compiler that implements the relevant part of the Fortran 2003 standard (or a Fortran 95 compiler that implements the so called "allocatable" TR).

    • An explicit interface to the procedure is required (the procedure must be a module procedure, an internal procedure or have an interface block in the calling scope).

    • The dummy argument must not be intent(in). If you are not using the allocation status or other aspects of the value of the dummy argument at all in the subroutine then intent(out) may be appropriate (if allocated beforehand the dummy argument will be automatically deallocated when the procedure is called), otherwise intent(inout) or no intent.

    (Your second block of example code has a syntax error with the deallocate statement - you should simply specify the xyzArray variable, leave off the (myshape) shape specification))

    For example, in a module:

    subroutine update(xyzArray)
      type(xyz), allocatable, intent(inout) :: xyzArray(:)
      ...
      if (allocated(xyzArray)) deallocate(xyzArray)
      allocate(xyzArray(newshape))
      ...
    

    这篇关于Fortran子例程的输入参数是否可以在子例程的主体中解除分配和分配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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