问题
I am trying to use fftpack with gfortran, but I am getting errors that i think relate to that some routines are passed complex arrays when the dummy argument is declared as real.
I read a comment on an intel fortran page that one could disable "check routine interface". Does anyone know if there is a similar option for gfortran?
I would like to not have to edit the fftpack... ( i guess this is because complex in memory is represented by two reals and the array arguments are passed as references but please correct me if I am wrong :) )
[to elaborate and meet the comments...] So after downloading the dfftpack from netlib and compiling as a standalone file (f77 I pressume) with all subroutines in the same file I get a warning for example in
SUBROUTINE DFFTF (N,R,WSAVE)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
DIMENSION R(1) ,WSAVE(1)
IF (N .EQ. 1) RETURN
CALL RFFTF1 (N,R,WSAVE,WSAVE(N+1),WSAVE(2*N+1))
RETURN
END
the waring appears when calling CALL RFFTF1 (N,R,WSAVE,WSAVE(N+1),WSAVE(2*N+1))
. The beginning of RFFTF1 looks like this...
SUBROUTINE RFFTF1 (N,C,CH,WA,IFAC)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
DIMENSION CH(*) ,C(*) ,WA(*) ,IFAC(*)
and the warning from compiling hits the actual argument WSAVE(2*N+1)
- to the dummy argument IFAC
: (output from code::blocks build log window)
mingw32-gfortran.exe -Jobj\Debug\ -Wall -g -c
C:\... \dfftpack.f -o obj\Debug\dfftpack.o
C:\... \dfftpack.f:345.40:
CALL RFFTB1 (N,R,WSAVE,WSAVE(N+1),WSAVE(2*N+1))
1 Warning: Type mismatch in argument
'ifac' at (1); passed REAL(8) to INTEGER(4)
I assume this will cause an incorrect result.. (the passing of a real to integer seems not to convert/round to the nearest integer but to something else. Does anyone know if it should be rounded in the call, like: NINT(WSAVE(2*N+1))
?
回答1:
I encountered this problem when I refactored FFTPACK 5.1 from FORTRAN 77 to Fortran 2008. I performed a C-language style cast without copying as follows:
use ISO_C_binding, only: c_f_pointer, c_loc
integer, parameter :: N = 42
complex, target :: c(N) ! Also works for the allocatable attribute
real, pointer :: r(:) => null()
! Pass memory address from complex array to real array
call c_f_pointer(c_loc(c), r, shape=[2*size(c)])
call procedure_expecting_real_arg(r, ....)
! Terminate association
nullify( r )
来源:https://stackoverflow.com/questions/30160456/gfortran-complex-actual-to-real-dummy-argument