On 09/27/2012 08:46 AM, Ian Harvey wrote:
> If I have a private binding in an extensible type that is in a
> particular module; I extend that type in another module and in that
> extended type I have a binding of the same name as the private binding
> in the parent type, does the binding in the extension type override the
> binding in the parent type?
Coincidence: I ran into exactly the same question last week and almost
posted it here, but sort of convinced myself that the behavior of my
compiler was fine ... but see below:
> [code elided]
>
> If the answer is yes, which is my guess based on what I've read and what
> my compiler seems to do
And my compiler says no.
> is the accessibility of the binding in the
> extension type influenced at all by the accessibility of the binding in
> the parent type? My guess being no - for the above example, objects with
> declared type tb have an accessible binding "proc" outside of module b,
> as opposed to the situation of objects of declared type ta outside of
> module a.
>
> So...
>
> USE a
> USE b
> CLASS(ta), ALLOCATABLE :: obj
> ALLOCATE(tb :: obj)
> CALL proc(obj) ! Prints "tb"
> ! CALL ta%binding ! Illegal
> SELECT TYPE (obj)
> CLASS IS (tb)
> CALL tb%binding ! Ok, prints "tb"
> END SELECT
> END
>
> [...]
Here is my example, which is essentially equivalent (I think, please
correct me if I'm wrong), but the compiler treats it differently:
---------------------------------------------------
module base
implicit none
public
type, abstract :: base_t
contains
procedure, nopass, private :: msg => base_msg
end type base_t
contains
subroutine base_msg ()
print *, "base type"
end subroutine base_msg
subroutine write_msg (t)
class(base_t), intent(in) :: t
call t%msg
end subroutine write_msg
end module base
module implementation
use base
implicit none
public
type, extends (base_t) :: concrete_t
contains
procedure, nopass :: msg => concrete_msg
end type concrete_t
contains
subroutine concrete_msg ()
print *, "concrete type"
end subroutine concrete_msg
end module implementation
program main
use base, only: write_msg
use implementation
implicit none
type(concrete_t) :: t1
class(base_t), allocatable :: t2
call write_msg (t1) ! prints "base type"
call t1%msg () ! prints "concrete type"
allocate (concrete_t :: t2)
call write_msg (t2) ! prints "base type"
! call t2%msg () ! rejected by the compiler (t2%msg
inaccessible)
select type (t2)
type is (concrete_t)
call t2%msg () ! prints "concrete type"
end select
end program main
-----------------------------------------------------------
So the output is:
base type
concrete type
base type
concrete type
-----------------------------------------------------------
I guess this makes sense. What does the standard say here?
-- Wolfgang
--
E-mail:
firstnameini...@domain.de
Domain: yahoo