Reputation: 141
With extended types in Fortran should a private component by visible to a type extension in a different module.
With both gcc4.7 and ifort the following code results in a error since bName is in both the initial type and the extension. But since it's private, it isn't accesible in the extension in a different module, i.e., if you comment out bName in the bar_type you will get an error that it's private.
module foo
type :: foo_type
character(256),private :: bName = "foo"
contains
procedure :: pName => pName
end type
contains
subroutine pName(this)
class(foo_type), intent(in) :: this
print*,trim(this%bName)
end subroutine
end module
module bar
use foo, only : foo_type
type,extends(foo_type) :: bar_type
character(256),private :: bName = "bar"
contains
procedure :: pName => pName
end type
contains
subroutine pName(this)
class(bar_type), intent(in) :: this
print*,this%bName
end subroutine
end module
program test
use foo, only : foo_type
use bar, only : bar_type
type(foo_type) :: foo_inst
type(bar_type) :: bar_inst
call foo_inst%pName()
call bar_inst%pName()
end program
If bar_type was contained in the same module as foo_type, then bName would be accessible from bar_type, i.e., the following code will compile
module foo
type :: foo_type
character(256),private :: bName = "foo"
contains
procedure :: pName => pName
end type
type, extends(foo_type) :: baz_type
contains
procedure :: pName => pName_baz
end type
contains
subroutine pName_baz(this)
class(baz_type), intent(in) :: this
print*,trim(this%bName)
end subroutine
subroutine pName(this)
class(foo_type), intent(in) :: this
print*,trim(this%bName)
end subroutine
end module
program test
use foo, only : foo_type,baz_type
type(foo_type) :: foo_inst
type(baz_type) :: baz_inst
call foo_inst%pName()
call baz_inst%pName()
end program
Been having a hard time parsing the standards to know what should happen in the first example.
Upvotes: 4
Views: 585
Reputation: 6649
I believe the first example is not standard-conforming.
Even though the private attribute makes the component bName
inaccessible outside module foo
, it is still inherited by bar_type
(perhaps rather pointless, because nothing can be done with it, but that's not the issue) -- see Note 4.51 in f2003:
Inaccessible components and bindings of the parent type are also inherited, but they remain inaccessible in the extended type. Inaccessible entities occur if the type being extended is accessed via use association and has a private entity.
So bar_type
has an inherited component with the name bName
, which makes it an error to add another component by that name (see paragraph 16.2 for scope and name rules).
Upvotes: 2