6

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,

Yuxiang Wang
  • 8,095
  • 13
  • 64
  • 95
  • 3
    `intent(out)` is inappropriate for the result. See http://stackoverflow.com/q/24170024/3157076 for more (among other) detail. – francescalus Jan 07 '15 at 20:30
  • @francescalus Thank you for your response! I went to the referenced question. Does that mean: for the variable `function_name`, it does not have an allocated address in the memory yet, so it is not a dummy variable pointing to the address of the output. Therefore, `intent(out)` would be illegal. Is that right? – Yuxiang Wang Jan 07 '15 at 20:38
  • "Dummy" just means the arguments to the function. In this case `a` and `b` _in_ the function. Intent can be specified for dummy variables only. – francescalus Jan 07 '15 at 20:45
  • @francescalus Oh OK! "Intent can be specified for the function arguments only". That totally explained it. Thanks a lot! Would you like to post that as an answer so I can accept it? – Yuxiang Wang Jan 07 '15 at 20:48

1 Answers1

10

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 ),

francescalus
  • 30,576
  • 16
  • 61
  • 96