Gfortran复杂实际到真正的虚拟参数

Gfortran复杂实际到真正的虚拟参数

本文介绍了Gfortran复杂实际到真正的虚拟参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在gfortran中使用fftpack,但是我得到的错误与我认为有些例程在伪参数被声明为真实时传递了复数数组有关。

我在英特尔fortran页面上阅读了一条评论,可以禁用检查例行界面。有谁知道gfortran是否有类似的选择?



我想不必编辑fftpack ...(我想这是因为内存中的复杂内容由两个实数表示,并且数组参数作为引用传递但请纠正我,如果我错了:))

[详细说明并符合注释...]
因此,从netlib下载dfftpack并编译作为一个独立的文件(f77我按)与所有子例程在同一个文件中我得到一个警告,例如在

  SUBROUTINE DFFTF N,R,WSAVE)
隐式双精度(AH,OZ)
DIMENSION R(1),WSAVE(1)
IF(N .EQ。1)RETURN
CALL RFFTF1(N,R,WSAVE,WSAVE(N + 1),WSAVE(2 * N + 1))
RETURN
END
/ code>。 RFFTF1的开头看起来像这样...
$ b $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b隐式双精度(AH,OZ)
维度CH(*),C(*),WA(*),IFAC(*)

以及编译时的警告命中实参 WSAVE(2 * N + 1) - 到伪参数 IFAC :(从code :: blocks构建日志窗口输出)

  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))
警告:类型不匹配参数
'ifac'at(1); (8)传递给INTEGER(4)

我认为这会导致错误的结果..(真正的整数传递似乎不是转换/舍入到最近的整数,而是其他的东西。有谁知道它是否应该在调用中舍入,如: NINT(WSAVE(2 * N + 1))

解决方案
当我将FORTRAN 77中的FFTPACK 5.1重构为Fortran时遇到此问题我执行了C语言风格的转换,而不复制如下:

 仅使用ISO_C_binding:c_f_pointer,c_loc 

integer,parameter :: N = 42
complex,target :: c(N)!也可用于allocatable属性
real,pointer :: r(:) => null ()

!将存储地址从复数组传递到实数组
call c_f_pointer(c_loc(c),r,shape = [2 * size(c)])

call procedure_expecting_real_arg(r,....)

!终止关联
nullify(r)


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))?

解决方案

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 )

这篇关于Gfortran复杂实际到真正的虚拟参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 12:36