2013-09-08 1 views
1

사용자 정의 함수를 입력으로 사용하는 프로 시저를 포함하는 기본 유형이 있습니다. 사용자 정의 함수는 확장 된 유형으로 정의됩니다. 다음은 ifort-13.1.3로 컴파일하지만 gfortran-4.8.1와 함께 실패gfortran은 특정 다형성 사례와 함께 실패합니다.

module m 

implicit none 

type, abstract :: base 
    contains 
    procedure :: use_f 
end type base 

type, extends(base) :: extended 
    contains 
    procedure :: f  
    procedure :: test ! calls use_f which takes f as argument 
end type extended 

contains 
subroutine f(this) 
    class(extended) :: this 
end subroutine f 

subroutine use_f(this, func) 
    class(base) :: this 
    interface 
    subroutine func(this) 
    import :: base 
    class(base) :: this 
    end subroutine func 
    end interface 
end subroutine use_f 

subroutine test(this) 
    class(extended) :: this 
    call this%use_f(f) ! This is the important part! 
end subroutine test 
end module m 

program a 
end program a 

gfortran가 나는 또한 프로 시저 포인터를 사용하여 시도했다

 call this%use_f(f) 
       1 
Error: Interface mismatch in dummy procedure 'func' at (1): Type/rank mismatch in argument 'this' 

을 생산하지만, gfortran이 실패하면서 여전히 ifort은 컴파일합니다. 이제 경우 대신 인터페이스 블록의 I 코드가 ifort와 gfortran 모두 성공적으로 컴파일 use_f에

external func 

을 넣어. 그러나 EXTERNAL 키워드가 시대에 뒤 떨어진 것이 아닌가? 더 표준에 부합하는 접근 방식이 효과가 있습니까?

답변

6

제시된 프로그램이 잘못되었습니다. 기술적으로 컴파일러가 진단서를 발행 할 필요는 없지만, ifort가 있어야한다고 기대할 수 있습니다. 그러나 이는 상황에 따라 적절할 수 있습니다. 인텔에 버그를보고하는 것이 좋습니다.

gfortran 오류 메시지에서 암시 하듯이 실제 프로 시저 인수와 더미 프로 시저 인수의 특성이 동일하지 않습니다. 더미의 인터페이스가 명시적일 때 F2008의 12.5.2.9p1에 의해 동일해야합니다. 여기서는 관련이없는 몇 가지 예외를 제외하십시오. 프로 시저의 특성에는 인수의 특성이 포함됩니다. 더미 데이터 인수의 특성에는 유형이 포함됩니다.

실제 프로 시저의 더미 인수 유형은 extended이고 더미 프로 시저의 더미 인수 유형은 base입니다.

func으로 설명 된 인터페이스를 사용하여 실제로 프로 시저를 호출하는 경우 해당 프로 시저에 실제 인수로 extended 유형의 객체를 전달하는 것이 유효 할 수 있습니다. 하지만 유형이 extended과 호환 될 수 있기 때문에 형식이 동일하지 않습니다.

dummy 프로 시저 인수의 인터페이스가 내재적 일 때 (EXTERNAL 문을 사용했기 때문에), 일치하는 특성 주변의 규칙이 완화됩니다. 즉, 다형성 인수가있는 프로 시저에는 명시적인 인터페이스가 있어야하므로 더미 프로 시저 인수는 사용할 수 없습니다.

외부 구문은 더 이상 사용되지 않지만 명시 적 인터페이스가 항상 제공되는 경우에는 필요하지 않습니다 (좋은 습관입니다).

extended의 바인딩과 모듈 절차로 모두 f가 있음에 유의하십시오. 실제 프로 시저 인수로 f을 참조하면 바인딩이 아닌 모듈 프로 시저를 참조하게됩니다. 표시하는 코드에서 바인딩으로 f을 갖는 점은 없습니다. 혼란이 없음을 확인하기 위해 프로 시저와 프로 시저에 대한 바인딩이있는 유형 간의 관계는 C++와 같은 다른 언어에서 사용되는 모델과는 포트란에서 다릅니다. 프로 시저는 결코 유형의 멤버가 아니며 바인딩은 있습니다. 완전히 다른 유형의 바인딩은 동일한 절차를 참조 할 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 위의 예제는 실제로 'f'가 일부 '확장 된'특정 변수와 프로 시저에 액세스해야하기 때문에 지나치게 단순화 된 것 같습니다. 나는 'f'를 구속력을 갖는 것보다 다른 어떤 방법도 보지 못합니다. 또한, "polymorphic 인자가있는 프로 시저에는 명시적인 인터페이스가 있어야하므로 더미 프로 시저 인수를 사용할 수 없습니다"라는 것을 잘 모르겠다.EXTERNAL 키워드를 사용하면 'f'가 서브 루틴에서 f (this, )를 호출하여 사용되며 이는 예상대로 작동합니다. –

+0

죄송합니다, 예제가 단순화 된 것을 잊었습니다. 나는 'f'가 서브 루틴에서 f (this)를 호출하여 사용된다고 말하고자했습니다. –

+0

나는 바인딩과 절차가 혼란 스럽다고 생각합니다. 예제 코드는 바인딩'f'를 전혀 참조하지 않습니다. 두 가지 가능성 - use_f는 프로 시저를 인수로 사용하여 전달되는 프로 시저에 유연성을 제공합니다. 인수 대신 실제로 구현해야하는 기본 유형의 지연 바인딩입니까? 그렇지 않다면, 프로 시저'f'의 인수는 class (base) 여야하며, SELECT TYPE을 사용하여 인수를 확장 된 유형의 객체로 사용할 수 있습니다 (실제 인수가 해당 유형이라고 가정). – IanH