Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fortran array cannot be returned in function: not a DUMMY variable

Being new to Fortran 90 free-form, I would really like to know why the following piece of code snippet would not work:

program test2
    implicit none
    !!! A program to practice f90 writing.
    ! Define double precision data
    integer, parameter :: dp = kind(1.d0)
    real(dp) :: a(3), b(3)
    integer :: i
    a = (/(i, i=1, 3)/)
    b = (/(i, i=1, 3)/)
    write (*, *) m31tensorprod(a, b)

contains
    function m31tensorprod(a, b)
        real(dp), dimension(3), intent(in) :: a, b
        real(dp), intent(out) :: m31tensorprod(3, 3)
        integer :: k1, k2
        forall(k1=1:3, k2=1:3)
            m31tensorprod(k1, k2) = a(k1) * b(k2)
        end forall
        return
    end function m31tensorprod
end program test2

When I try to compile this via gfortran test2.f90, it says:

test2.f90:13.4:

function m31tensorprod(a, b)
1 Error: Symbol at (1) is not a DUMMY variable

I thought because m31tensorprod is an internal function, it shouldn't need to be declared. Where did I do wrong?

Thanks,

like image 459
Yuxiang Wang Avatar asked Jan 07 '15 20:01

Yuxiang Wang


1 Answers

You are correct that m31tensorprod being an internal function means that you do not have to declare it in the main program. In the jargon: it has an explicit interface.

However, that is not the problem with your code. What is going wrong is with the function definition itself. [Admittedly the compiler message isn't too helpful.]

The definition of the function subprogram

function m31tensorprod(a, b)

defines a function with result variable m31tensorprod. This result variable is subject to your declaration

    real(dp), intent(out) :: m31tensorprod(3, 3)

It is this declaration which is incorrect. You may declare type (real(dp)) and dimension ((3,3)) but the intent(out) is erroneous.

The intent attribute, in the words of the Fortran standard, is subject to the constraint (C538)

An entity with the INTENT attribute shall be a dummy data object or a dummy procedure pointer.

Coming back to the compiler message, m31tensorprod is not a dummy variable. In this case the dummy arguments are a and b. In general the dummy arguments are those things between the ( and the ),

like image 189
francescalus Avatar answered Sep 21 '22 13:09

francescalus