Jeremy_Tamu
Jeremy_Tamu

Reputation: 755

Fortran about creating function

When I compile the program below, I have an error as

Return type mismatch of function 'j17' (unknown/real(4))"

program Jfun

    implicit none
    real :: R = 1.5, X1 = 2.5, X3 = 4.8, EPS1 = 0.5
    write(*,*) J17(R,X1,X3,EPS1)

end program Jfun

real function J17(R,X1,X3,EPS1)

    implicit none
    real, intent(in) :: R,X1,X3,EPS1
    J17 = -((R+X1-EPS1)*(X3**2-R**2)+(X3**2)*R)/(R**3)/((R+X1-EPS1)**2)

end function J17

How do I solve this?

Upvotes: 1

Views: 57

Answers (1)

casey
casey

Reputation: 6915

Gfortran emits a second error that is more helpful than the one you've posted:

jfun.f90:5:14:

     write(*,*) J17(R,X1,X3,EPS1)
              1
Error: Function ‘j17’ at (1) has no IMPLICIT type

Within your main program you haven't provided a type for j17 and because implicit typing is disabled (a good thing), the compiler cannot determine a type for it. The error you posted is a consequence of this one that unknown (in your main program) and real (in your function) are not matching types.

To fix this, make your main program aware of the type of j17. You can do this by simply declaring it in your main program

real :: j17

This will set the type of the external function reference to real and this will compile. This is not ideal however, as there is no checking of function arguments. For that, an explicit interface is helpful. You can write an explicit interface by hand, but it is much easier to let the compiler generate it for you.

One method is to make j17 an internal function:

program Jfun

  implicit none
  real :: R = 1.5, X1 = 2.5, X3 = 4.8, EPS1 = 0.5
  write(*,*) J17(R,X1,X3,EPS1)

contains

  real function J17(R,X1,X3,EPS1)

    implicit none
    real, intent(in) :: R,X1,X3,EPS1
    J17 = -((R+X1-EPS1)*(X3**2-R**2)+(X3**2)*R)/(R**3)/((R+X1-EPS1)**2)

  end function J17
end program Jfun

and another method is to put j17 into a module:

module jfunc
contains

  real function J17(R,X1,X3,EPS1)

    implicit none
    real, intent(in) :: R,X1,X3,EPS1
    J17 = -((R+X1-EPS1)*(X3**2-R**2)+(X3**2)*R)/(R**3)/((R+X1-EPS1)**2)

  end function J17
end module jfunc

program Jfun
  use jfunc
  implicit none
  real :: R = 1.5, X1 = 2.5, X3 = 4.8, EPS1 = 0.5
  write(*,*) J17(R,X1,X3,EPS1)

end program Jfun

Both of these methods provide the compiler with information about the function j17's return type and dummy arguments. This lets the compiler do type,kind,rank checks and is also mandatory if you want to take advantage of certain language features like returning arrays or passing certain kinds of arguments.

Upvotes: 5

Related Questions