Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
公告
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Access Issues

Blane_J_
新分销商 I
1,169 次查看

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.

 

0 项奖励
6 回复数
IanH
名誉分销商 III
1,169 次查看

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`.

0 项奖励
Blane_J_
新分销商 I
1,169 次查看

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 ?

0 项奖励
Mark_Lewy
重要分销商 I
1,169 次查看

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.

0 项奖励
jimdempseyatthecove
名誉分销商 III
1,169 次查看

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

0 项奖励
Blane_J_
新分销商 I
1,169 次查看

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.

0 项奖励
Blane_J_
新分销商 I
1,169 次查看

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.

0 项奖励
回复