Gfortran complex actual to real dummy argument

2020-04-20 14:01发布

问题:

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 )