Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
870 views
in Technique[技术] by (71.8m points)

arrays - Can a input argument of a Fortran subroutine be deallocated and allocated in the body of the subroutine?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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))
  ...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...