How can a scalar be passed to a vector (1D array) to a Fortran subroutine?

There is this program:

INTEGER i,k
REAL*8  mp(15,48)
REAL*8  sp(15)
k=0
do i=1,12
   k=k+1
   call Equaltensors(sp,mp(1,k),15)
enddo
end

c=====================

subroutine Equaltensors(tensA,tensB,n)
REAL*8 tensA(n),tensB(n)
INTEGER i
do   i=1,n
     tensB(i)=tensA(i)
enddo
return
end

So basically the value of mp(1,1) and so on is passed to the subroutine as a vector tensB(15) with n=15. What I don't understand is how a real number can be stored in a one-dimension array in a subroutine.


The title of your question is a bit misleading. Fortran doesn't allow you to pass a scalar to an array. But what it DOES allow is passing a single element of an array to a routine's array dummy argument - this is called "sequence association" in Fortran. As IanH and others have said, the following elements are automatically associated with the elements of the dummy array, up to the last element in the called routine's actual array.

There are some restrictions on this feature, though. If the element is of a POINTER array,you can't do this.

Going back to your title, I have seen many programs pass, say, the constant 3 to a routine where the dummy is an array. The routine only uses the first element, but this is not legal and newer compilers may detect the error and complain. One workaround for this is to turn the argument into an array by using an array constructor - for example, CALL FOO ([3]), but this works only if the value is to be read, not written.

I've written some blog posts on this general issue - see http://software.intel.com/en-us/blogs/2009/03/31/doctor-fortran-in-ive-come-here-for-an-argument and http://software.intel.com/en-us/blogs/2009/07/10/doctor-fortran-in-ive-come-here-for-an-argument-side-2


EDIT: corrected per the comment by IanH, who points out that the behavior is guaranteed without making assumptions about the argument passing convention.

This approach started in early FORTRAN, by assuming that the argument is being passed as an address, typically called "call by reference". The address of scaler mp(1,k) is the address of the first element of this column k. Since Fortran stores arrays in column major format (http://en.wikipedia.org/wiki/Row-major_order#Column-major_order), the 15 values of the kth column will be sequential in memory. So if the called subroutine interprets this address as that of a 1-D array tensB of length 15, it will access the elements of the kth column.

In modern Fortran one could write the argument in a clearer manner by selecting a column with an array slice: mp (:,k).