修复FORTRAN IV警告:“参数的数量与intrinsinc程序不兼容,假设'外部'”

时间:2015-10-08 09:40:53

标签: fortran intel-fortran

我需要运行一个旧的FORTRAN IV代码(我应该运行得很好)。我下载了英特尔编译器的试用版,并尝试使用以下命令编译我给出的源文件:

ifort  -f66 abel.for -o mycode

其中abel.for是源文件的名称。我收到了一堆警告和错误。我想问一下我给出的第一个警告:

The number of arguments is incompatible with intrinsinc procedure, assume 'external'.  [KNOT]

其中KNOT是一个定义为:

的函数
C                                                                       AAOK0162
C  PROCEDURE FOR LOCATING THE SPLINE SECTION TO WHICH AN                AAOK0163
C  ARGUMENT BELONGS.                                                    AAOK0164
C        N    NUMBER OF KNOTS IN THE SPLINE REPRESENTATION              AAOK0165
C        U    KNOTS POSITION                                            AAOK0166
C        X    THE ARGUMENT WHOSE SPLINE SECTION IS SOUGHT               AAOK0167
C        I    THE NUMBER OF THE SMALLEST KNOT LARGER THAN X             AAOK0168
C                                                                       AAOK0169
      INTEGER FUNCTION KNOT(N,U,X)                                      AAOK0170
      IMPLICIT REAL*8(A-H,O-Z)                                          AAOK0171
      DIMENSION U(1)                                                    AAOK0172
C TEST WHETHER POINT IN RANGE                                           AAOK0173
      IF (X.LT.U(1)) GOTO 990                                           AAOK0174
      IF (X.GT.U(N)) GOTO 990                                           AAOK0175
C ESTIMATE KNOT INTERVAL BY ASSUMING EQUALLY SPACED KNOTS               AAOK0176
      J=DABS(X-U(1))/(U(N)-U(1))*(N-1)+1                                AAOK0177
C ENSURE CASE X=U(N) GIVES J=N-1                                        AAOK0178
      J=MIN0(J,N-1)                                                     AAOK0179
C SEARCH FOR KNOT INTERVAL CONTAINING X                                 AAOK0180
      IF (X.GE.U(J)) GOTO 11                                            AAOK0181
2     J=J-1                                                             AAOK0182
      IF(X.LT.U(J)) GOTO 2                                              AAOK0183
      GOTO 7                                                            AAOK0184
1     J=J+1                                                             AAOK0185
11    IF(X.GT.U(J+1)) GOTO 1                                            AAOK0186
7     KNOT=J+1                                                          AAOK0187
      RETURN                                                            AAOK0188
990   KNOT=-1                                                           AAOK0189
      RETURN                                                            AAOK0190
      END                                                               AAOK0191

并且编译器错误指示从后续子例程(行AAOK0211)调用此函数:

      SUBROUTINE ABEL1(N,IN,X,XN,A,B,C,D,YCALC)                         AAOK0201
      IMPLICIT REAL*8 (A-H,O-Z)                                         AAOK0202
      DIMENSION X(1),XN(1),A(1),B(1),C(1),D(1),YCALC(1)                 AAOK0203
      COMMON /R/ R                                                      AAOK0204
      COMMON /PI/ PI                                                    AAOK0205
      DO 70 L=1,IN                                                      AAOK0206
      R=X(L)                                                            AAOK0207
      IF(R.EQ.0.D0) R=1.D-6                                             AAOK0208
      YCALC(L)=0.D0                                                     AAOK0209
      IF (R.EQ.XN(N+1)) R=R-1.D-6                                       AAOK0210
      I=KNOT(N+1,XN,R)                                                  AAOK0211
      IF(I.EQ.-1) GOTO 70                                               AAOK0212
      IF(I.EQ.N+1) GOTO 99                                              AAOK0213
      DO 60 K=I,N                                                       AAOK0214
      X1=XN(K)                                                          AAOK0215
      X2=XN(K+1)                                                        AAOK0216
      S=3.D0*A(K)*DI1(2,X1,X2)+2.D0*B(K)*DI1(1,X1,X2)+C(K)*DI1(0,X1,X2) AAOK0217
      YCALC(L)=YCALC(L)+S                                               AAOK0218
60    CONTINUE                                                          AAOK0219
99    X2=XN(I)                                                          AAOK0220
      S=3.D0*A(I-1)*DI1(2,R,X2)+2.D0*B(I-1)*DI1(1,R,X2)                 AAOK0221
     *       +C(I-1)*DI1(0,R,X2)                                        AAOK0222
      YCALC(L)=-(YCALC(L)+S)/PI                                         AAOK0223
70    CONTINUE                                                          AAOK0224
      RETURN                                                            AAOK0225
      END                                                               AAOK0226

我想问一下是什么原因引起了这个警告,是否可以安全地忽略它?

1 个答案:

答案 0 :(得分:1)

KNOT()NOT函数的非标准特定内部函数,它接受8字节整数(参见https://docs.oracle.com/cd/E19422-01/819-3684/3_F77_Intrins.html)。

在这种情况下,您确实可以忽略警告。由于参数的数量和类型不同,编译器不会无意中调用内在函数,因此它是安全的。问题是如果编译器具有看起来完全相同但执行不同的功能。 external语句用于防止此类冲突。

你可以做的就是通过放置

来告诉编译器你有自己的外部函数KNOT()
EXTERNAL *KNOT

在每个编译单元的声明部分中调用KNOT,例如,

SUBROUTINE ABEL1(N,IN,X,XN,A,B,C,D,YCALC)
      IMPLICIT REAL*8 (A-H,O-Z)
      EXTERNAL *KNOT

根据您的隐式输入规则,类型应该是正确的,但您可以通过

明确指定它
      INTEGER KNOT

注意: *中的EXTERNAL *KNOT表示不应使用内在函数,而应使用用户提供的函数。这种行为不同于现代Fortran!请参阅http://h21007.www2.hp.com/portal/download/files/unprot/fortran/docs/lrm/lrm0633a.htm在FORTRAN 77及更高版本中仅使用EXTERNAL KNOT