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

发布于 2024-12-11 22:27:08 字数 1164 浏览 0 评论 0原文

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

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

我从父例程中调用它:

umwmTime1=getTime(umwmStartTimeStr)
umwmTime2=getTime(umwmStopTimeStr)

其中 umwmTime 1 和 2 声明为:

TYPE timeType
  INTEGER :: yyyy,mo,dd,hh,mm,ss
ENDTYPE timeType
TYPE(timeType) :: umwmTime1,umwmTime2

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

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

第 282 行和 283 行点是函数调用在父例程中。

但是,如果我使用子例程(而不是函数)来获取 umwmTime1 和 umwmTime2 作为 INTENT(OUT) 参数,则不会出现任何问题。我对这个函数做错了什么?

I have a simple function that returns a time object based on a time string:

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

I call it from the parent routine as:

umwmTime1=getTime(umwmStartTimeStr)
umwmTime2=getTime(umwmStopTimeStr)

where umwmTime 1 and 2 are declared as:

TYPE timeType
  INTEGER :: yyyy,mo,dd,hh,mm,ss
ENDTYPE timeType
TYPE(timeType) :: umwmTime1,umwmTime2

The compile error message I get is:

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

Lines 282 and 283 point are function calls in the parent routine.

However if I use subroutine (instead of function) to get umwmTime1 and umwmTime2 as INTENT(OUT) arguments, I get no problems. What am I doing wrong with the function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

放我走吧 2024-12-18 22:27:08

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

例如,在一个简单的单文件程序中,您提供的代码在 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

The problem is the compiler doesn't know that the timetype you defined in the main program is the same as the timetype that you defined in the function. You should define that one place, preferably in a module, and let that define the type everywhere.

For instance, in a simple one-file program, the code you provided doesn't work for me in gfortran, but this does:

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
来世叙缘 2024-12-18 22:27:08

将函数“getTime”放入模块中,并在调用例程中使用该模块。

问题是调用例程不知道例程函数 getTime 返回 TYPE(timeType)。默认情况下,getTime 被视为实标量值。因此,您需要一个可以通过 USE 语句轻松提供的显式接口。该接口也可以由 INTERFACE 块提供,但不建议这样做,因为容易出错。

我还想指出,参数 timeStr 的声明“CHARACTER(len=19)”是非常危险的。我建议:事实上

FUNCTION getTime(timeStr)RESULT(time)
IMPLICIT NONE
CHARACTER(LEN=*),INTENT(IN) :: timeStr
...

,任何使用少于 19 个字符的字符串参数调用该函数都是错误的。

Put you function "getTime" within a module and USE that module in the calling routine.

The problem is that the calling routine does not know that the routine function getTime returns a TYPE(timeType). By default, getTime is considered as a real scalar value. Therefore, you need an explicit interface which is easily provided by a USE statement. This interface may be also provided by an INTERFACE block but this is not advised because error prone.

I would like also to point out that the declaration "CHARACTER(len=19)" of the argument timeStr is very dangerous. I suggest instead :

FUNCTION getTime(timeStr)RESULT(time)
IMPLICIT NONE
CHARACTER(LEN=*),INTENT(IN) :: timeStr
...

Indeed any call to that function with a string argument having less that 19 characters is wrong.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文