- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My problem comes in this way:
module proto implicit none public type, abstract :: tp1 contains private generic, public :: ge => sub procedure(Isub), pass, deferred :: sub generic, public :: operator(==) => sub end type tp1 abstract interface function Isub(this, a) import tp1 logical :: Isub class(tp1), intent(in) :: this class(*), intent(in) :: a end function Isub end interface end module proto module inst use proto implicit none private public :: tp2 type, extends(tp1) :: tp2 integer :: s contains private procedure, pass :: sub end type tp2 contains function sub(this, a) implicit none logical :: sub class(tp2), intent(in) :: this class(*), intent(in) :: a integer :: tmp select type(a) type is(integer) tmp = a class default tmp = 0 end select if(this % s == tmp)then sub = .true. else sub = .false. end if return end function sub end module inst program main use inst type(tp2) :: t if(t == 12) write(*,*) "yes" ! FirstLine: This is bad. if(t % ge(12)) write(*,*) "yes" ! SecondLine: This is good. end
When comments out the FirstLine in main, compiler says nothing, but When comments out the SecondLine, the FirstLine generates a link error says unresoved external symbol _PROTO_mp_SUB.
And in addtion, if I do not use operator == but another self-defined operator(anyone, here assume .op.), both FirstLine and SecondLine work normally. Did I misused it? Thanks in advance for any suggestion.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code is non-conforming, as clarified by interpretation F08/0052. Different versions of the compiler deal (or fail to deal) with the non-conformance in different ways, and it is plausible that there are still issues - there have been threads about this here in the last few months.
The type tp1 has a private deferred binding `sub`. Because it is private, outside the module `proto` that binding is inaccessible - it cannot be referenced by name or overridden. The type tp2 also has a binding called sub, but because the binding of the same name in the parent type is inaccessible, this is a different binding. The deferred binding in the parent type is not overridden but it is inherited, this inheritance of a deferred binding means that the type tp2 should be abstract. The compiler should diagnose this with a relevant message - it doesn't, which is a compiler bug, but the link errors that you do see are somewhat of a consequence of the error in the program.
A private deferred binding in a type always means that non-abstract extensions of that type cannot be defined outside of the module (or its descendants) that has the type with a private deferred binding.
If you make the sub binding public in type tp1, then things perhaps work as you expect.
(The code is also non-conforming, in that function sub ends up referencing the undefined variable `this%s`.)
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code is non-conforming, as clarified by interpretation F08/0052. Different versions of the compiler deal (or fail to deal) with the non-conformance in different ways, and it is plausible that there are still issues - there have been threads about this here in the last few months.
The type tp1 has a private deferred binding `sub`. Because it is private, outside the module `proto` that binding is inaccessible - it cannot be referenced by name or overridden. The type tp2 also has a binding called sub, but because the binding of the same name in the parent type is inaccessible, this is a different binding. The deferred binding in the parent type is not overridden but it is inherited, this inheritance of a deferred binding means that the type tp2 should be abstract. The compiler should diagnose this with a relevant message - it doesn't, which is a compiler bug, but the link errors that you do see are somewhat of a consequence of the error in the program.
A private deferred binding in a type always means that non-abstract extensions of that type cannot be defined outside of the module (or its descendants) that has the type with a private deferred binding.
If you make the sub binding public in type tp1, then things perhaps work as you expect.
(The code is also non-conforming, in that function sub ends up referencing the undefined variable `this%s`.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks lanH, your explanation is clear enough and I think as it is called an abstract type, all entities within it should always be public to descendants. so only make overridens that override the deferred bindings private should always be a good solution.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page