Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Get the size of an array in a subroutine

Status
Not open for further replies.

sebastian11986

Programmer
Apr 17, 2012
2
DE
Hi there,

i work with fortran77 and the nonstandards from 90/95

my code is like this:

integer array(10)
->i filled the array
size(array) ->this works
call test(array)
-------------------------------------
subroutine(arr)
integer arr(*)
size(arr)->does not work in the subroutine and i need the size in the following code of the routine.

of course i could use:
call test(array,size(array))
-----------------------------------
subroutine test(arr,size)
integer array(size)

but i have to use the function a few hundred times, so it would be perfect, if i could get the size in the subroutine and don't have to write "size(array)" in the "test()".

Thanks for your help

Sebastian



 
i work with fortran77 and the nonstandards from 90/95

Then I do not know if you can achieve this, for you have to make sure, that your compiler supports the fortran 90/95 features used here.

In mikrom's first example, the function is programmed as an internal procedure, that is, it is contained in the body - and program unit - of the calling main program. This might be awkward to handle, when your progs get longish, or might create a real problem when you want to call your routine from different program units.

My choice would be to explicitly interface your program. Looks like this

Code:
	program testrun
	implicit none

	interface
		subroutine sub (iVal)    ! name of program to be interfaced
			integer, intent(in), dimension (:) :: iVal    ! repeat type declarations of the arguments
		end subroutine    ! and you are ready to go.
	end interface

	integer ival (12)
	integer irslt
	integer j

	do j = 1, size (iVal)
		ival(j) = j
	enddo

	call sub (iVal)
	stop
	end
!
!
!
	subroutine sub (iVal)
	implicit none

	integer, intent(in), dimension (:) :: iVal
	integer j

	do j = 1, size (iVal)
		write (*,*) ival(j)
	enddo

	return
	end

This gave me a printout of the numbers 1 to 12 created in the subroutine. Works with functions as well.

Norbert


The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
Just as a matter of interest, which compiler are you using?
 
Is this subroutine that is going to be called with the array as argument going to be called for various arrays? of various lengths?

is that the point?

Otherwise, for as long as you are using fortran 77 and not going to be using allocatable and the size of the array is actually hard coded in the program...what's wrong with making the same declaration inside the subroutine? Whether you type it every time or type it once in some "include file" and just include wherever you need such declaration:

File: var.inc
Code:
      integer arr(10)
Program:
Code:
      include 'var.inc'
      call sub(arr)
      end      
      subroutine sub(arr)
      include 'var.inc'
      write(*,*) "size of array is ", size(arr)
      end


 
Thanks for all your help!

- I'm using compaq visual fortran, with fixed source format. (The programm i'm working with was started a few years ago ;) )

- Unfortunately i don't know how to figure out which compiler the programm is using.

SUBOUTINE TEST(ARR)
REAL, DIMENSION:))::ARR causes no error, but it doesn't seem to work:
WRITE(*,*) ARR => Stack Overflow
WRITE(*,*) ARR(1) => Access violation
WRITE(*,*) SIZE(ARR) gives back everything else than the right size

- salgerman, you are right, i want to call the subroutine for various arrays with various length. So i don't want to define all variables as global/common blocks
 
OP didn't post an working example, which demonstrates the problem but IMO when size() works in his program outside of the routine then it is supported by the compiler and it should work inside of a routine too. In other case it would be probably a problem with compiler.

In case that it really doesn't work the classical method is to provide the array dimension as an argument of the function/subroutine:
Code:
subroutine array_sub(array, n)
  implicit none
  integer :: n, i
  real :: array(n)
  ...
  ...
end subroutine array_sub
...
real function array_foo(array, n)
  implicit none
  integer :: n, i
  real :: array(n)
  ...
  ...
end function array_foo
 
sebastian11986,
I didn't have Compaq Visual Fortran, but you can try to debug your program to where the error occurs. Examine the array before the call of the subroutine TEST and then in the subroutine.
 
I am working with the Compaq compiler, using free format however. And here mikrom's version - passing the number of array's elements as an argument in the call to the subroutine - works as well. The advantage of using explicit interfacing - as I did propose - is a somewhat better errorchecking at compilation time, but this is a minor benefit only.

One tip: You can mix free-format and fixed-format fortran program files. Not within the same file - at least I did not test this. But if you add new files to the old prog, you are free to switch to free format - which is much better to use in my opinion. Imagine an unlimited length of line !

BTW if you use free format or fixed format coding - the compiler is the same. And my Compaq version 6.6 is a 90/95 compiler.

Norbert

The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top