函数返回类型不匹配 [英] Function return type mismatch

查看:413
本文介绍了函数返回类型不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Fortran中重新编写一个旧的C ++程序来利用LAPACK(我知道C ++确实有LAPACK ++,但是我在安装时遇到了很多麻烦,所以我放弃了)。



我原本没有编译问题,但是当我将所有变量声明为 REAL 时。当我开始编写需要LAPACK的程序部分时,我发现所有传递给 DSYEV 的参数都必须是 DOUBLE PRECISION 。所以我试图把所有的东西都改成双精度(包括将所有硬编码的数字改成它们的双精度对应值,即0.0 - > 0.0D0)现在,当我尝试编译时,我得到了所有函数和子例程的以下错误已经写过:

 错误:函数返回类型不匹配< function> (1)(REAL(4)/ REAL(8))

我不确定在哪里这是来自于,因为程序中的所有内容已经改变为双精度。



例如,我声明如下:

双精度:: A1(3),A2(3) ,D1(3),D2(3)
双精度:PI
PI = 3.14159265359D0
alpha =(/0.109818D0,0.405771D0,2.2766D0 /)
d = (/0.444635D0,0.535328D0,0.154329D0/)

do 10 i = 1,3

A1(i)= alpha(i)* zeta1 ** 2.0D0 $(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

以及函数:

 子程序createS(S,A1,A2,D1,D2,r)
双精度A1(3),A2(3),D1(3),D2(3)
双精度r
双精度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继续
80继续
S(2,1)= S(1, 2)
返回
结束

双精度函数getS(a,b,r)
双精度:PI
双精度a,b, r
双精度:: S
PI = 3.14159265359D0
S =(PI /(a + b))** 1.5D0
S = S * dexp( - (a * b * r * r)/(a + b))
getS = S
return
end

然后我得到错误

  HFSTO3G.f:85.28:

S(1,2)= S(1,2)+ getS(A1(i),A2(j),r)* D1(i)* D2(j)
1
错误:函数'gets'在(1)(REAL(4)/ REAL(8))返回类型不匹配

我正在使用gfortran进行编译。这可能是问题吗?我对编程并不陌生,但是对于Fortran来说是新的。

解决方案

您是否将子例程和函数放入模块中,并且使用那个模块?否则,可能发生的情况是,您在子程序createS中隐式地输入getS作为单精度实数,但实际上它返回的是双精度。另一个建议:总是使用隐式无来查找未声明的变量。如果您忘记在源代码中包含 implicit none ,gfortran会提供编译器选项 -fimplicit-none 。隐式类型是有害的,Fortran可能会继续支持遗留代码。

双精度也是过时的,但比隐式类型风险小得多。如果您有最新版本的gfortran,您可以使用以下内容:

 使用ISO_FORTRAN_ENV 
real(real64)::

查看gfortran手册。

编辑:隐式无将getS的类型从real(4)(通过隐式键入)更改为unknown(未声明类型,隐式键入禁用)。如果将过程放入模块中,它们将知道其他类型:函数返回和参数类型。这将修复这个错误。它还可以帮助编译器找到其他错误,但可以检查调用与过程参数之间的参数一致性。请参阅正确使用fortran中的模块,子例程和函数计算Fortran中两个向量的叉积90 的例子。


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.

解决方案

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.

这篇关于函数返回类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆