Function return type mismatch

£可爱£侵袭症+ 提交于 2019-12-18 07:09:04

问题


I'm attempting to recode an old C++ program in Fortran to make use of LAPACK (I'm aware that C++ does have LAPACK++, but I'm having a lot of trouble installing it, so I gave up).

I originally didn't have any problems with compilation, but that was when I had all variables declared as REAL. When I started coding the section of the program that required LAPACK, I found that all parameters passed to DSYEV need to be DOUBLE PRECISION. So I tried to change everything to double precision (including changing all hard coded numbers to their double precision counterparts, i.e. 0.0 -> 0.0D0) Now when I try to compile, I get the following error for all of the functions and subroutines that I've written:

    Error: Return type mismatch of function <function> at (1) (REAL(4)/REAL(8))

I'm not sure where this is coming from, as everything in the program has been changed to double precision.

For example, I've declared the following:

double precision :: alpha(3),d(3),zeta1,zeta2
double precision :: A1(3),A2(3),D1(3),D2(3)
double precision :: PI
PI = 3.14159265359D0
alpha = (/0.109818D0, 0.405771D0, 2.22766D0/)
d = (/0.444635D0, 0.535328D0, 0.154329D0 /)

do 10 i=1,3

A1(i) = alpha(i)*zeta1**2.0D0
A2(i) = alpha(i)*zeta2**2.0D0
D1(i) = d(i)*(2.0D0*A1(i)/PI)**(3.0D0/4.0D0)
D2(i) = d(i)*(2.0D0*A2(i)/PI)**(3.0D0/4.0D0)

10  continue

And the function:

subroutine createS(S,A1,A2,D1,D2,r)
double precision A1(3),A2(3),D1(3),D2(3) 
double precision r
double precision S(2,2)
integer :: i,j
S(1,1) = 1.0D0
S(2,2) = 1.0D0
do 80 i=1,3
do 90 j=1,3

S(1,2) = S(1,2) + getS(A1(i),A2(j),r)*D1(i)*D2(j)

 90 continue
 80 continue
S(2,1) = S(1,2)
return
end

double precision function getS(a,b,r)
double precision :: PI
double precision a,b,r
double precision :: S
PI = 3.14159265359D0
S = (PI/(a+b))**1.5D0
S = S*dexp(-(a*b*r*r)/(a+b))
getS = S
return
end

And then I get the error

  HFSTO3G.f:85.28:

  S(1,2) = S(1,2) + getS(A1(i),A2(j),r)*D1(i)*D2(j)                 
                        1
  Error: Return type mismatch of function 'gets' at (1) (REAL(4)/REAL(8))

I'm using gfortran to compile. Could that be the issue? I'm not new to programming, but new to Fortran. Not programming this in Fortran is not an option.


回答1:


Did you put your subroutines and functions into a module and use that module? Otherwise, probably what is occurring is that you are getting implicit typing of getS in subroutine createS as a single precision real but it actually returns a double precision. Another suggestion: always use implicit none to find undeclared variable. In case you forget to include implicit none in your source code, gfortran provides the compiler options -fimplicit-none. Implicit typing is pernicious and likely continued in Fortran to support legacy code.

P.S. double precision is also obsolete but much less risky than implicit typing. If you have a recent version of gfortran you can use the following:

use ISO_FORTRAN_ENV
real (real64) ::

See the gfortran manual.

EDIT: The implicit none changed the type of getS from real(4) (by implicit typing) to unknown (no type declared, implicit typing disabled). If you place the procedures into a module, they will "know" each others types: function returns and argument types. This will fix this bug. It also helps the compiler find other bugs but enabling it to check the consistency of arguments between the call and the arguments of the procedure. See Correct use of modules, subroutines and functions in fortran and Computing the cross product of two vectors in Fortran 90 for examples.




回答2:


You are not declaring getS as a function in the subroutine createS. You need to add double precision, external :: getS in your variable declarations of the subroutine createS.




回答3:


replace double precision with:

REAL (Kind=8)
INTEGER (Kind=4)
COMPLEX (Kind=8)


来源:https://stackoverflow.com/questions/16741252/function-return-type-mismatch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!