- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, everyone. I'd like to suggest the following code:
module test1 implicit none type :: a integer :: sa end type a end module test1 module test2 use test1 implicit none type,extends(a) :: b private integer :: sb end type b end module test2 program main use test2 implicit none type(b) :: var write(*,*) var%sa ! sa can be accessed. write(*,*) var%sb ! sb is blocked. end program main
Here comes the question: How can I block sa to be seen from the outside of the type defination module test2 ? In other words how can sa made to be a private variable within type b ? Appriciate any ideas and many thanks.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Given the code you show, make the `sa` component private. Module `test2` doesn't access it.
If module `test2` does require access, then fortran's accessibility model does not permit the degree of control you request, if you require the types to be defined in different modules.
Conceptually, because type `b` extends type `a`, an object of type `b` is also an object of type `a`. A characteristic of type `a` is that is has an accessible component named `sa` outside its defining module, and so type `b` has that same characteristic.
If type `a` and type `b` were defined in the same module, the the `sa` component could be made private.
If, conceptually, an object of type `b` should not also be considered an object of type `a`, then consider using composition rather than inheritance - make an object of type `a` a component of type `b`, rather than type `b` extending type `a`.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ianh wrote:
Given the code you show, make the `sa` component private. Module `test2` doesn't access it.
If module `test2` does require access, then fortran's accessibility model does not permit the degree of control you request, if you require the types to be defined in different modules.
Conceptually, because type `b` extends type `a`, an object of type `b` is also an object of type `a`. A characteristic of type `a` is that is has an accessible component named `sa` outside its defining module, and so type `b` has that same characteristic.
If type `a` and type `b` were defined in the same module, the the `sa` component could be made private.
If, conceptually, an object of type `b` should not also be considered an object of type `a`, then consider using composition rather than inheritance - make an object of type `a` a component of type `b`, rather than type `b` extending type `a`.
Thanks IanH, as you suggested, I made the sa component to be private, but another problem comes up. Assume the change Like:
module test1 implicit none type :: a private ! <---- Add PRIVATE here. integer :: sa end type a end module test1 module test2 use test1 implicit none type,extends(a) :: b private integer :: sa ! <---- Add another sa component here. !!! INVALID !!! integer :: sb end type b end module test2 program main use test2 implicit none type(b) :: var write(*,*) var%sa write(*,*) var%sb end program main
When I add another sa component within type b, the compiler says:
error #8205: A component declared in an extended type cannot have the same name as any accessible component of its parent type. [SA]
Since sa is private in type a and it is inaccessible outside of test1, why can't I declare another sa in type b ?
The compiler's behavior gives me the thought that type b has an invisible and inaccessible component sa, so you cannot declare the same sa once again, what is mistake here ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Not that I'd recommend this practice, but it would appear that the Fortran standard should allow you to define a component with the same name as an inaccessible component in the parent type.
In section 4.5.7.2 of the Fortran 2008 and 2015 standards, you have two notes:
NOTE 4.53
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.
NOTE 4.55
A component or type parameter declared in an extended type shall not have the same name as any accessible
component or type parameter of its parent type.
The fact that a%sa is private by use association would suggest that b%sa ought to be a valid component.
But, even if the declaration of sa in type b compiled, your main program should fail to compile because the components of b are private.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As structured in #3, the sa within type a would only be accessible by a contains section within the type declaration. Since there is no type bound procedure, you could construct a unique GUID and tack it onto the type's sa:
integer :: sa_YourNewlyGeneratedGUIDhere
And, if you later add a type bound procedure, you can use the uniquely named sa in the procedure.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Mark Lewy wrote:
Not that I'd recommend this practice, but it would appear that the Fortran standard should allow you to define a component with the same name as an inaccessible component in the parent type.
In section 4.5.7.2 of the Fortran 2008 and 2015 standards, you have two notes:
NOTE 4.53
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.NOTE 4.55
A component or type parameter declared in an extended type shall not have the same name as any accessible
component or type parameter of its parent type.The fact that a%sa is private by use association would suggest that b%sa ought to be a valid component.
But, even if the declaration of sa in type b compiled, your main program should fail to compile because the components of b are private.
Thanks Mark, I've read the part you mentioned about the standard and have found that limitation there, so it's all about the standard issue.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
As structured in #3, the sa within type a would only be accessible by a contains section within the type declaration. Since there is no type bound procedure, you could construct a unique GUID and tack it onto the type's sa:
integer :: sa_YourNewlyGeneratedGUIDhere
And, if you later add a type bound procedure, you can use the uniquely named sa in the procedure.
Jim Dempsey
Thanks Jim, your suggestion should be a way. Since I am willing to use the identical sa name within type b which the standard disallow, I think it should be the time to change the design somehow.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page