- 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