使用函数调用非法使用派生类型

mil*_*cic 1 fortran fortran90

我有一个简单的函数,它返回一个基于时间字符串的时间对象:

FUNCTION getTime(timeStr)RESULT(time)
IMPLICIT NONE
CHARACTER(LEN=19),INTENT(IN) :: timeStr
TYPE timeType
 INTEGER :: yyyy,mo,dd,hh,mm,ss
ENDTYPE timeType
TYPE(timeType) :: time
READ(UNIT=timeStr( 1: 4),'(I4)')time%yyyy
READ(UNIT=timeStr( 6: 7),'(I2)')time%mo
READ(UNIT=timeStr( 9:10),'(I2)')time%dd
READ(UNIT=timeStr(12:13),'(I2)')time%hh
READ(UNIT=timeStr(15:16),'(I2)')time%mm
READ(UNIT=timeStr(18:19),'(I2)')time%ss
ENDFUNCTION getTime
Run Code Online (Sandbox Code Playgroud)

我从父例程中将其称为:

umwmTime1=getTime(umwmStartTimeStr)
umwmTime2=getTime(umwmStopTimeStr)
Run Code Online (Sandbox Code Playgroud)

其中umwmTime 1和2声明为:

TYPE timeType
  INTEGER :: yyyy,mo,dd,hh,mm,ss
ENDTYPE timeType
TYPE(timeType) :: umwmTime1,umwmTime2
Run Code Online (Sandbox Code Playgroud)

我得到的编译错误消息是:

PGF90-S-0099-Illegal use of derived type (ESMF_interface_UMWM.F90: 282)
PGF90-S-0099-Illegal use of derived type (ESMF_interface_UMWM.F90: 283)
  0 inform,   0 warnings,   2 severes, 0 fatal for umwm_component_run
Run Code Online (Sandbox Code Playgroud)

第282行和第283行是父例程中的函数调用.

但是,如果我使用子程序(而不是函数)将umwmTime1和umwmTime2作为INTENT(OUT)参数,我没有遇到任何问题.我的功能有什么问题?

Jon*_*rsi 6

问题是编译器不知道您在主程序中定义的时间类型与您在函数中定义的时间类型相同.您应该定义一个位置,最好是在一个模块中,并让它在任何地方定义类型.

例如,在一个简单的单文件程序中,您提供的代码在gfortran中对我不起作用,但这样做:

MODULE timeTypeDef
TYPE timeType
    INTEGER :: yyyy,mo,dd,hh,mm,ss
ENDTYPE timeType
END MODULE timeTypeDef

PROGRAM foo
USE timeTypeDef
IMPLICIT NONE

TYPE(timeType) :: umwmTime1, umwmTime2

umwmTime1=getTime('2010-10-10-14:39:03')
umwmTime2=getTime('2011-11-11-09:17:53')

contains

FUNCTION getTime(timeStr)RESULT(time)
    USE timeTypeDef
    IMPLICIT NONE
    CHARACTER(LEN=19),INTENT(IN) :: timeStr
    TYPE(timeType) :: time

    READ(UNIT=timeStr( 1: 4),FMT='(I4)')time%yyyy
    READ(UNIT=timeStr( 6: 7),FMT='(I2)')time%mo
    READ(UNIT=timeStr( 9:10),FMT='(I2)')time%dd
    READ(UNIT=timeStr(12:13),FMT='(I2)')time%hh
    READ(UNIT=timeStr(15:16),FMT='(I2)')time%mm
    READ(UNIT=timeStr(18:19),FMT='(I2)')time%ss
ENDFUNCTION getTime

END PROGRAM foo
Run Code Online (Sandbox Code Playgroud)