Christoph90
Christoph90

Reputation: 673

Writing assumed-size array causes "upper bound shall not be omitted..."

I am writing code to add on a closed-source Finite-Element Framework that forces me (due to relying on some old F77 style approaches) in one place to rely on assumed-size arrays.

Is it possible to write an assumed-size array to the standard output, whatever its size may be?

This is not working:

module fun

implicit none

contains

subroutine writer(a)
integer, dimension(*), intent(in) :: a
write(*,*) a
end subroutine writer

end module fun


program test
use fun
implicit none

integer, dimension(2) :: a

a(1) = 1
a(2) = 2

call writer(a)

end program test

With the Intel Fortran compiler throwing

error #6364: The upper bound shall not be omitted in the last dimension of a reference to an assumed size array.

Upvotes: 6

Views: 3288

Answers (2)

francescalus
francescalus

Reputation: 32451

An assumed-size array may not occur as a whole array reference when that reference requires the shape of the array. As an output item in a write statement that is one such disallowed case.

So, in that sense the answer is: no, it is not possible to have the write statement as you have it.

From an assumed-size array, array sections and array elements may appear:

write (*,*) a(1:2)
write (*,*) a(1), a(2)
write (*,*) (a(i), i=1,2)

leading simply to how to get the value 2 into the subroutine; at other times it may be 7 required. Let's call it n.

Naturally, changing the subroutine is tempting:

subroutine writer (a,n)
  integer n
  integer a(n)      ! or still a(*)
end subroutine

or even

subroutine writer (a)
  integer a(:)
end subroutine

One often hasn't a choice, alas, in particular when associating a procedure with a dummy procedure with a specific interface . However, n can get into the subroutine through any of several other ways: as a module or host entity, or through a common block (avoid this one if possible). These methods do not require modifying the interface of the procedure. For example:

subroutine writer(a)
  use aux_params, only : n
  integer, dimension(*), intent(in) :: a
  write(*,*) a(1:n)
end subroutine writer

or we could have n as an entity in the module fun and have it accesible in writer through host association. In either case, setting this n's value in the main program before writer is executed will be necessary.

Upvotes: 2

The compiler does not know how large an assumed-size array is. It has only the address of the first element. You are responsible to tell how large it is.

 write(*,*) a(1:n)

Equivalently you can use an explicit-size array

integer, intent(in) :: a(n)

and then you can do

write(*,*) a

Upvotes: 3

Related Questions