【问题标题】:Error: If selector expression in SELECT TYPE is not a named variable, associate-name=> shall appear错误:如果 SELECT TYPE 中的选择器表达式不是命名变量,则应出现 associate-name=>
【发布时间】:2014-09-26 20:45:05
【问题描述】:

我正在尝试在另一种类型中使用一种类型。但是,我就是不能让它编译。对我来说很奇怪:选择类型的东西在主程序中有效,但在类型的子程序中无效。

module ModBuffer
    implicit none
    private
    type, abstract, public :: Buffer
    contains
        procedure, public                       :: Constructor
    endtype Buffer

    type, extends(Buffer), public :: BufferR
        real(8), allocatable, public            :: BufData(:,:,:)
    endtype BufferR

    type, extends(Buffer), public :: BufferI
        complex(8), allocatable, public         :: BufData(:,:,:)
    endtype BufferI

    contains

    subroutine Constructor(this, dim1, dim2, dim3)
        class(Buffer), intent(inout)            :: this
        integer, intent(in)                     :: dim1, dim2, dim3

        select type(this)
        type is(BufferR)
            allocate(this%BufData(dim1, dim2, dim3))
        type is(BufferI)
            allocate(this%BufData(dim1, dim2, dim3))
        endselect
    endsubroutine Constructor
endmodule ModBuffer

module ModSystem
    use ModBuffer
    implicit none
    private
    type, public :: System
        class(Buffer), allocatable, public :: WF
    contains
    endtype System

    type, extends(System) :: NewSystem
    contains
        procedure, public :: Constructor
    endtype NewSystem

    contains

    subroutine Constructor(this, Flag)
        class(NewSystem), intent(inout) :: this
        logical, intent(in) :: Flag

        if(Flag) then
            allocate(BufferR::this%WF)
        else
            allocate(BufferI::this%WF)
        endif
        select type(this%WF)
        type is(BufferR)
            print *, "Buffer is real."
        type is(BufferI)
            print *, "Buffer is complex."
        endselect
    endsubroutine Constructor
endmodule ModSystem


program test
    use ModSystem
    !use Operation
    class(System), allocatable :: s

    allocate(NewSystem::s)
    call s%Constructor(.true.)
endprogram test

select type(this%WF) 行出现编译错误。但是如果我在主程序中定义一个Buffer类型,做同样的事情,就不会出错了。

错误信息是:

error #8253: If selector expression in SELECT TYPE is not a named variable, associate-name=> shall appear.

如何编译这段代码?

【问题讨论】:

  • 我个人不会对此投反对票,但有些人对“不起作用”和“我遇到错误”过敏,但没有具体说明它如何不起作用以及错误看起来如何像。可能没有人会投票支持real(8),尽管这不是一个非常好的做法。
  • 同意 Vladimir F 我还要补充一点:代码很多,这真的是最简单/最普遍的问题吗?您说这适用于修改:修改是什么?确切的错误信息也很有用:我们希望其他项目中遇到相同问题的人能够找到答案。对于知道答案的人来说,这也是一个有用的提示。
  • @VladimirF 你能否解释一下“没有人可能会投票否决它的真实性(8)”。我认为 real(8) 是“双精度”的替代品。而且我知道使用变量来指定“种类”要好得多。请告诉我更多关于你的意见。谢谢。
  • 参见 stackoverflow.com/questions/838310/fortran-90-kind-parameter/…stackoverflow.com/questions/22362211/… kind=8 在不同的平台上可能意味着不同的东西。便携式解决方案使用select_real_kindiso_fortran_enviso_c_binding

标签: compiler-errors fortran fortran2003


【解决方案1】:

没有理由使用指针,只是使用select type 的关联部分(你没有写错误消息,但IIRC它很有描述性):

   select type (twf => this%WF)

【讨论】:

  • 太棒了!像魅力一样工作。
【解决方案2】:

我不知道为什么这个话题被否决。但我找到了解决方案。顺便说一句,我在 Windows 上使用 IVF(几个月没有更新)。

似乎我不能在“选择类型”子句中使用类型的成员来触发 IVF 编译器错误。但是如果你设置一个指向成员的指针,一切都会正常工作。有点连线指针解决问题,没有多大意义。

module ModBuffer
    implicit none
    private
    type, abstract, public :: Buffer
    contains
        procedure, public                       :: Constructor
    endtype Buffer

    type, extends(Buffer), public :: BufferR
        real(8), allocatable, public            :: BufData(:,:,:)
    endtype BufferR

    type, extends(Buffer), public :: BufferI
        complex(8), allocatable, public         :: BufData(:,:,:)
    endtype BufferI

    contains

    subroutine Constructor(this, dim1, dim2, dim3)
        class(Buffer), intent(inout)            :: this
        integer, intent(in)                     :: dim1, dim2, dim3

        select type(this)
        type is(BufferR)
            allocate(this%BufData(dim1, dim2, dim3))
        type is(BufferI)
            allocate(this%BufData(dim1, dim2, dim3))
        endselect
    endsubroutine Constructor
endmodule ModBuffer

module ModSystem
    use ModBuffer
    implicit none
    private
    type, public :: System
        class(Buffer), allocatable, public :: WF
    contains
    endtype System

    type, extends(System), public :: NewSystem
    contains
        procedure, public :: Constructor
    endtype NewSystem

    contains

    subroutine Constructor(this, Flag)
        class(NewSystem), intent(inout) :: this
        logical, intent(in) :: Flag
        class(Buffer), pointer :: P

        if(Flag) then
            allocate(BufferR::this%WF)
        else
            allocate(BufferI::this%WF)
        endif
        call SetPointer(P, this%WF)
        select type(P)
        type is(BufferR)
            print *, "Buffer is real."
        type is(BufferI)
            print *, "Buffer is complex."
        endselect
    endsubroutine Constructor

    subroutine SetPointer(MyP, MyA)
        class(Buffer), pointer :: MyP
        class(Buffer), target :: MyA
        MyP => MyA
    endsubroutine SetPointer
endmodule ModSystem


program test
    use ModSystem
    !use Operation
    class(System), allocatable :: s

    allocate(NewSystem::s)
    select type(s)
    type is(NewSystem)
        call s%Constructor(.true.)
    endselect
endprogram test

【讨论】:

    猜你喜欢
    • 2020-04-17
    • 1970-01-01
    • 2016-04-10
    • 2010-11-27
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多