Community
cancel
Showing results for 
Search instead for 
Did you mean: 
kolber__Michael
New Contributor I
72 Views

error 6220

I got this error declaring an array passed into a subroutine as x(I,i).  The message says only the right index can be of assumed size.  How do I solve this issue?

 

Thanks.

0 Kudos
7 Replies
mecej4
Black Belt
72 Views

If x(L,*) is a 2-D array, the number of declared rows should be known in the subroutine. Thus, you my either pass L as an additional argument (this is the standard way for BLAS and Lapack routines),or make x an assumed shape array, in which case you need to provide an interface to this subroutine available to every caller of the subroutine.

It may also be worth considering to make X a local allocatable array instead of making it an argument. However, this is only feasible if the new values placed into X in the subroutine are of no further interest after the subroutine returns.

Steve_Lionel
Black Belt Retired Employee
72 Views

Something is missing here. The declaration you show is not an assumed-size array. Please show the actual declaration and the actual error message.

What you have looks like an "adjustable array" - a dummy argument where the bounds are given by another variable. Or, and it's unclear from your post, you've shown us the actual argument passed in yet asked about an error in the called procedure (not shown.)

mecej4 is correct in saying that if you are declaring an assumed-size array, with one of the bounds as *, that * must be the rightmost. I don't know if that's actually what you're doing.

kolber__Michael
New Contributor I
72 Views

The array had been pre defined to be (46,300000) but most of the time that may locations are not needed.  This is legacy code and only the new parts are using modules and interfaces.  It is a very complicated modeling application and management does not want me to try and change to much.  But, memory is becoming an issue.

The variable is allocated in a subroutine and then all other subroutines that need it get it .  I changed the declaration in one of the receiving subroutines to be real*8( : , :) and did not get any errors on that.

 

mecej4
Black Belt
72 Views

kolber, Michael wrote:

The variable is allocated in a subroutine and then all other subroutines that need it get it .  I changed the declaration in one of the receiving subroutines to be real*8( : , :) and did not get any errors on that.

That's because the compiler believed that you told it the truth. You will have promoted a compile time error to a run  time error. Worse, the run time error may be experienced by someone else than you, and that person may have no way of fixing the code. Will the user bless you?

kolber__Michael
New Contributor I
72 Views

Steve,

 

What is the best way to accomplish this task.  I cannot rewrite the entire application to use modules.  They are just not ready for that yet.  I currently am the only one on the team who has any experience with the new Fortran.

kolber__Michael
New Contributor I
72 Views

If I allocate the size of the array in a subroutine what is the best way to declare it in the calling routine,  It is 2 dimensional and the first dimension will always be 46.

Steve_Lionel
Black Belt Retired Employee
72 Views

You still haven't shown us what you actually did, so I have to guess.

If you want to allocate an an array in a subroutine, an explicit interface is required. That's the same if you use an assumed-shape array (:,:). You are not required to put the subroutine in a module, though that is the preferred way. Instead you can write INTERFACE blocks, put THOSE in a module, and USE that module where needed.

Here's an example: Let's say you have an existing routine that looks like this:

subroutine sub (a)
real, dimension(42,30000) :: a
...

and you want to have sub allocate the array to the desired size.

First, create a module (we'll call it intmod.f90):

module intmod
implicit none
interface
  subroutine sub (a)
  real, allocatable, intent(inout) :: a(:,:)
  end subroutine sub
end interface
end module intmod

Now in the main program (or wherever you want to call sub), you'd do this:

program mymain
use intmod

real, allocatable :: somearray(:,:)
...
call sub (somearray)

Subroutine sub can then ALLOCATE a to whatever bounds it wants, and on return, somearray will now have those bounds. You can find out what they are, if needed, using the UBOUND intrinsic function.

Does this help?