2014-09-26 6 views
-1

다른 형식의 형식을 사용하려고합니다. 그러나 컴파일 만 할 수는 없습니다. 나에게 이상한 점은 select 프로그램은 주 프로그램에서 작동하지만 서브 루틴에서는 작동하지 않는다는 것입니다.FORTRAN : 형식 컴파일 오류 선택

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 

"유형 선택 (이 % WF)"줄에 컴파일 오류가 있습니다. 그러나 주 프로그램에서 버퍼 유형을 정의하고 동일한 작업을 수행하면 오류가 발생하지 않습니다. 코드를 컴파일하기위한 제안? 감사. 두 의견

편집

감사합니다.

위치 :

select type(this%WF) 

오류 메시지가이 :

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

솔루션에 대한 블라디미르 F의 대답으로 이동하십시오. 핵심은 문제를 해결하기 위해 연관을 사용하는 것입니다. 멤버를 직접 사용하면 오류가 발생합니다. 나는 오류를 재현하는 더 좋은 방법이 있기 때문에 francescalus에 동의한다. 그러나 블라디미르 F에게서 언제 대답을 얻었는지 모르겠다.

+2

나는이 투표하지 않을 아래로, 개인적으로, 그러나 어떤 사람들은 "작동하지 않는다"는 알레르기 반응을 나타내며 그것이 작동하지 않는 방법과 오류가 어떻게 나타나는지 명시하지 않고 "나는 오류가 있습니다." 아무도 아마 '진짜 (8)'를 위해 그것을 투표 할 것이다. 그러나 이것이 아주 건전하지는 않다. –

+0

블라디미르 F와 동의 함 나는 또한 추가 할 것이다 : 많은 코드가있다, 이것은 정말로 문제가있는 가장 간단하고 가장 일반적인 덩어리인가? 당신은 수정과 함께 작동한다고 : 그 수정은 무엇입니까? 정확한 오류 메시지는 또한 유용합니다. 우리는 다른 프로젝트에서 같은 문제를 가진 사람들이 답을 찾을 수 있기를 바랍니다. 또한 답을 알고있는 사람에게 유용한 프롬프트입니다. – francescalus

+0

@VladimirF "아무도 아마 진짜 (8)에 투표하지 않을 것"에 대해 조금 더 설명해 주실 수 있습니까? 제 생각에 real (8)은 "double precision"을 대체합니다. 그리고 변수를 사용하여 "kind"를 지정하는 것이 훨씬 낫다는 것을 알고 있습니다. 당신의 의견에 대해 좀 더 말해주세요. 감사. – FortCpp

답변

3

(오류 메시지를 기록하지 못했지만, IIRC 꽤 설명입니다) 단지 select type의 관련 부분을 사용하여 포인터를 사용하는 이유 :

select type (twf => this%WF) 
+0

좋아요! 매력처럼 작동합니다. – FortCpp

0

나는이 주제가 왜 투표 다운인지 전혀 모른다. 그러나 나는 해결책을 찾는다. BTW, 나는 몇 달 동안 업데이 트하지 않은 창문에 IVF를 사용하고 있습니다.

IVF 컴파일러 오류를 트리거하기 위해 "select type"절에서 유형의 멤버를 사용할 수없는 것 같습니다. 그러나 멤버에 대한 포인터를 설정하면 모든 것이 올바르게 작동합니다. 문제를 해결하기 위해 포인터를 조금 묶어 놓은 것이고 그것은별로 의미가 없습니다.

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