Silverfrost Forums

Welcome to our forums

Allocated array error-Reason?

23 Jan 2014 4:10 #13611

Hello,

Please can anyone help me here. I can't get this working but really need to...

I have delclared an allocatable array in a module as below.

MODULE MyModule   

double precision, ALLOCATABLE :: My_Allocated_Array(:) 

END MODULE MyModule

I have a subroutine defined as

subroutine MySubRoutineA

USE  MyModule

ALLOCATE My_Allocated_Array(15)

..... //I do something with My_Allocated_Array
call MySubRoutineB (
(My_Allocated_Array)

I know that I do not need to pass necessarily pass My_Allocated_array to MySubRoutineB . Let us say I pass

Now,

MySubRoutineB (My_Array_New_Name)

dimension My_Array_New_Name(*)

..............

I get an error on compilation stating that

Error 1 Error: The type of the actual argument differs from the type of the dummy argument. [My_Allocated_Array]

Can anyone please help? I have an old fortran code edited and I need this to work.

Is there soemthing fundamentally wrong?

Please help if possible, gratefully appreciated

Christy

24 Jan 2014 4:00 #13616

Please can John or anyone advise? I shall be grateful.

24 Jan 2014 5:52 #13618

Try using assumed-shape array, something like:

program test
  integer, allocatable :: a(:)

  allocate(a(5));
  a = (/1,2,3,4,5/);

  call test2(a)

contains
  subroutine test2(array)
    integer :: array(:)

    write(*,*) array

  end subroutine test2

end program test
24 Jan 2014 7:42 #13619

change:

MySubRoutineB (My_Array_New_Name)

dimension My_Array_New_Name(*)

to:

MySubRoutineB (My_Array_New_Name)

double precision My_Array_New_Name(*)

29 Jan 2014 7:46 #13638

@John- Tried but didn't work.

@jalih- it does not give error but gives a warnign stating:

Warning: Required interface for passing assumed shape array is missing from original source

Can the warning be neglected?

29 Jan 2014 8:45 #13639

You could simplify the declarations and not use (:) syntax, which requires an interface definition, (unless it is a requirement ?)

The following example does this and you should be able to adapt to your problem

MODULE MyModule    

double precision, ALLOCATABLE :: My_Allocated_Array(:) 

END MODULE MyModule

subroutine MySubRoutineA 

USE  MyModule 

ALLOCATE ( My_Allocated_Array(15) )

!..... //I do something with My_Allocated_Array 

call MySubRoutineB (My_Allocated_Array, size(My_Allocated_Array) )

...

MySubRoutineB (My_Array_New_Name, n)  
! transfer the dimension rather than use an interface for the dimension

integer  n
double precision My_Array_New_Name(n) 

.............. 

or

MODULE MyModule    

real*8, ALLOCATABLE :: My_Allocated_Array(:) 

END MODULE MyModule

subroutine MySubRoutineA 

USE  MyModule 

ALLOCATE ( My_Allocated_Array(15) )

!..... //I do something with My_Allocated_Array 

call MySubRoutineB (My_Allocated_Array, 15)  !  size(My_Allocated_Array) = 15

...

subroutine MySubRoutineB (My_Array_New_Name, n)  

! transfer the dimension rather than use an interface for the dimension

integer  n
real*8   My_Array_New_Name(n) 
29 Jan 2014 1:12 #13642

Thanks John,

  1. When I use ALLOCATABLE arrays, it permits me to use very huge array size.

Doing that (as in your code snippet), will it permit me to use very huge arrays (of size say 3 million or even more?)?

  1. If I do not pass the size of the array - is there any other option available?

Thanks again

29 Jan 2014 9:56 #13646
  1. You should use an error test on allocate, as:

ALLOCATE ( My_Allocated_Array(15), stat=istat ) if ( ISTAT /= 0) then ! respond to error

arrays of 3 million should not be a problem, as you could have up to 1,500 million bytes available.

  1. If the subroutine MySubRoutineB needs to know the size of the array, then it must be provided. You can use an interface block or more simply provide it as an argument, as I have shown. Alterntively you could not provide the array size, as: real8 My_Array_New_Name() and then use it. You can write the code ensuring you don't overflow the array size. The compiler will not be able to check this.

John

30 Jan 2014 6:30 #13648

Thanks John,

This is an existing code I'm modifying.

I do not intend using an argument as you provided (if possible)

Now, you say about an interface block.

Already there is a definition as below (elsewhere)

MODULE MyModule    

double precision, ALLOCATABLE :: My_Allocated_Array(:) 

END MODULE MyModule 

Where should the interface block be provided i.e. I'm actually repeating the same definition, right?

30 Jan 2014 11:59 #13656

I think you would be better off to 'USE MyModule' in MySubRoutineB and not change the name of the array.

MODULE MyModule    

real*8, ALLOCATABLE :: My_Allocated_Array(:) 

END MODULE MyModule 

subroutine MySubRoutineA 

USE  MyModule 

ALLOCATE ( My_Allocated_Array(15) ) 

!..... //I do something with My_Allocated_Array 

call MySubRoutineB (other_arguments)
... 

subroutine MySubRoutineB (other_arguments)  
USE  MyModule, My_Array_New_Name => My_Allocated_Array
integer other arguments
...

You can use (something like?) the example above to link the local name to the variable name in the module but I would not recommend this approach. Keep it simple!

John

31 Jan 2014 8:20 #13659

Thanks John

Did you mean the statement, My_Array_New_Name ⇒ My_Allocated_Array

alllows to use the array name as

My_Array_New_Name instead of original
My_Allocated_Array that was declared in MODULE?

2 Feb 2014 10:59 #13664

christyleomin,

Yes that is what I meant. A good document to use is the Lahey Language Reference .pdf, as it has a good alphabetical list of most Fortran structures. lahey.com > Support > Documentation > Express Language Reference

John

Please login to reply.