繁体   English   中英

在Fortran77过程中减少输出数组的维数

[英]Reduction of output array dimension in Fortran77 procedure

我正在处理一个大型的Fortran代码,其中的部分是用FORTRAN77编写的。 有一段代码,导致调试器引发如下错误:

Fortran runtime error: 
Index '2' of dimension 1 of array 'trigs' above upper bound of 1

但是,如果在不使用调试选项进行编译的情况下运行,则不会使程序崩溃。 使用的调试选项:

-g -ggdb -w -fstack-check -fbounds-check\
     -fdec  -fmem-report -fstack-usage

有问题的代码的逻辑如下:在文件variables.cmn我声明

implicit none

integer factors,n
real*8 triggers
parameter (n=32)

common /fft/ factors(19), triggers(6*n)

变量factorstriggers在过程initialize

include 'variables.cmn'
...
CALL FFTFAX(n,factors,triggers)
...

FFTFAX在另一个过程中声明为:

SUBROUTINE FFTFAX(N,IFAX,TRIGS)
implicit real*8(a-h,o-z)
DIMENSION IFAX(13),TRIGS(1)

    CALL FAX (IFAX, N, 3)
    CALL FFTRIG (TRIGS, N, 3)

RETURN
END

让我们看一下程序FFTRIG

  SUBROUTINE FFTRIG(TRIGS,N,MODE)
  implicit real*8(a-h,o-z)
  DIMENSION TRIGS(1)

        PI=2.0d0*ASIN(1.0d0)
        NN=N/2
        DEL=(PI+PI)/dFLOAT(NN)
        L=NN+NN

        DO 10 I=1,L,2
        ANGLE=0.5*FLOAT(I-1)*DEL
        TRIGS(I)=COS(ANGLE)
        TRIGS(I+1)=SIN(ANGLE)
10 CONTINUE
        DEL=0.5*DEL
        NH=(NN+1)/2
        L=NH+NH
        LA=NN+NN

        DO 20 I=1,L,2
        ANGLE=0.5*FLOAT(I-1)*DEL
        TRIGS(LA+I)=COS(ANGLE)
        TRIGS(LA+I+1)=SIN(ANGLE)
20 CONTINUE

FFTFAXFFTRIG过程中,参数的大小与实际输入数组大小的边界不同(对于TRIGS ,分别为1和19)。 我打印出来TRIGS调用后FFTFAX在无调试编译设置:

 trigs:                    1.0000000000000000        0.0000000000000000\
  0.99144486137381038       0.13052619222005157       0.96592582628906831\
  0.25881904510252074       0.92387953251128674       0.38268343236508978\
  ...

我的问题是:

  1. 表示法:DIMENSION TRIGS(1)不仅仅是设置数组的界限吗?
  2. 为什么该程序甚至可以在无调试器模式下运行?
  3. 如果我希望变量触发是该过程的结果,则是否设置:DIMENSION TRIGS(*)是一个很好的解决方法?

在f77语句中,例如DIMENSION TRIGS(1)或类似或带有任何数字的..(*),如果与该过程的参数有关,则仅告诉编译器数组的等级,必须将内存中的长度分配给该数组在子程序的调用中给出,通常f77不检查! 我的建议是使用(*)或将格式更好的格式(如有必要)重新格式化为f90到f90(显示的位将进行编译而不会发生变化...)。 并使用在子例程/过程的声明中使用n计算的维。 Fortan通过地址传递参数(例如,子例程中的trigs(i)只会引用内存位置,该位置对应于trigs(1)+ i * size(real * 8)的地址)。

编写子例程代码的更通用的方法可能是:

SUBROUTINE FFTRIG(TRIGS,N,MODE)
!   implicit real*8(a-h,o-z)
integer, intent(in) :: n      
real(kind=8)        :: trigs(6*n)
integer             :: mode
!  DIMENSION TRIGS(1)
.....
    PI=2.0d0*ASIN(1.0d0)
.....

或编译器检查的能力较低

SUBROUTINE FFTRIG(TRIGS,N,MODE)
!   implicit real*8(a-h,o-z)
integer, intent(in) :: n      
real(kind=8)        :: trigs(:)
integer             :: mode
!  DIMENSION TRIGS(1)
.....
    PI=2.0d0*ASIN(1.0d0)
.....

为了回答您的问题,我将TRIGS(1)更改为TRIGS(*),只是为了更清楚地标识数组TRIGS为未提供尺寸。 TRIGS(1)是F77之前版本的遗留物,用于识别此内容。

使用TRIGS(:)是不正确的,因为以这种方式定义数组TRIGS要求任何调用FFTRIG的例程都具有INTERFACE定义。 此更改将导致其他错误。

您的问题是将调试器对数组大小的需求与语法(不包括所提供的大小)混合在一起。 为了克服这个问题,您可以将数组TRIGS的声明维作为额外的声明参数传递给调试器进行检查。 使用“调试器”模式时,某些编译器确实提供了隐藏的属性,包括所有数组的声明大小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM