簡體   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