debugging - 减少 Fortran77 过程中的输出数组维数
问题描述
我正在编写一个大型 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\
...
我的问题是:
- 符号:DIMENSION TRIGS(1) 不仅仅是设置数组的界限吗?
- 为什么程序甚至在无调试器模式下工作?
- 如果我希望变量 trigs 是过程的结果,设置:DIMENSION TRIGS(*) 是否是一个很好的解决方法?
解决方案
在 f77 语句中,如 DIMENSION TRIGS(1) 或类似的或具有任意数字的 ..(*),如果与过程的参数有关只是告诉编译器数组的等级,则内存中的长度必须分配给数组在子程序的调用中给出,通常 f77 不检查这个!我的建议是使用 (*) 或更好地将 f77 源重新格式化(如有必要)为 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)
.....
推荐阅读
- python - 检查熊猫中的csv文件是否为空
- c - '\0' 和 printf() 在 C
- python - 如何从比特币核心分析比特币区块链数据?
- typescript - TypeScript:需要两个解构参数之一
- python - pandas.DataFrame.round() 在所需位数后不截断十进制值
- python - 抛出 'Xbyak::Error' what(): can'tprotect 的实例后调用终止
- java - 从 Playground 测试端点时出现 Google Amp 403 禁止错误
- java - 使用 Elasticsearch 依赖项时出现 Apache Lucene 错误
- vue.js - 将 buildDir 添加到 Nuxt 配置会破坏 Vuetify
- vue.js - 从 VueJS 子组件中的数组中删除项目