[英]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)
变量factors
和triggers
在过程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
在FFTFAX
和FFTRIG
过程中,参数的大小与实际输入数组大小的边界不同(对于TRIGS
,分别为1和19)。 我打印出来TRIGS
调用后FFTFAX
在无调试编译设置:
trigs: 1.0000000000000000 0.0000000000000000\
0.99144486137381038 0.13052619222005157 0.96592582628906831\
0.25881904510252074 0.92387953251128674 0.38268343236508978\
...
我的问题是:
在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.