Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

PUBLIC/PRIVATE module hierarchy

andrew_4619
Honored Contributor III
1,214 Views

When you have PRIVATE in a module header all entities in any modules that are inclued with USE automatically become private. Is they any way of modifying this behaviour so that public entifities in the sub module are still public?

For example in program fred below I would like to have access to the public entities in modules A and B. 

[fortran]program fred

use A

!do stuff

end program fred

module A

use module B

private

public :: some stuff

end module A

module B

private :: some stuff

public :: lots of stuff

end module B

[/fortran]

0 Kudos
7 Replies
IanH
Honored Contributor III
1,214 Views

No.

In A you need to explicitly give those entities from B that you want to be public entities of A the public attribute "again".

You could also create a module C that has PUBLIC default accessibility and simply USEs A and B - basically C becomes the top level module, with both A and B being "sub modules".

("submodule" in Fortran has a different meaning to the way it is being used here.)

0 Kudos
andrew_4619
Honored Contributor III
1,214 Views

Thanks for the clarification. In this instance I removed the default "private" in the top level module and then made each item explicitly public or private in the top level module as there weren't that many entries in this case.

Option 1) looks tiresome repeated work in many instances. Option 2) has potential...

I guess an optional language feature on the USE statement to import the public/private attributes would have been helpful 

(BTW I was using "sub" in the english rather than the fortran sense, but perhaps not the best term to use, in retrospect perhaps "nested" would have been better....)

0 Kudos
IanH
Honored Contributor III
1,214 Views

That sort of capability is something I've half wished for previously too.

An aside, that I mention because when it was first explained to me (not that long ago) I was rather surprised - it is easy for unintended things to become public entities of a module if you don't have the default accessibility of the module set to PRIVATE.  For example:

[fortran]MODULE m
  IMPLICIT NONE
  INTEGER, PARAMETER :: array(2,2) = RESHAPE([1,1,1,1],[2,2])
END MODULE m[/fortran]

the name "reshape" is a public entity of this module.  Did the programmer intend this?  In this case the use of a particular intrinsic as an initializer is really implementation detail for module m, but because I've overlooked the PRIVATE :: reshape statement (after all, I'm not declaring anything called RESHAPE, so why would I put that in?) it leaks out.  In scopes where this module is then used without an ONLY clause you cannot do the normal Fortran thing of hiding the intrinsic name with your own definition of the name reshape. 

(At the time of this realisation for me there was then a discussion about whether the INTEGER type also became a public entity of the module, and if so could you rename it, etc... I can't remember the answer (I think the answer has to be "NOOOOO!!!!!!" otherwise just parsing statements would be impossible) but the whole concept made my head spin.)

Consequently, very simple situations aside (such as an aggregator module that basically consists of USE statements only), I very much tend to make all modules have private accessibility by default.

0 Kudos
andrew_4619
Honored Contributor III
1,214 Views

Intesting, I will need to rethink a little....

0 Kudos
FortranFan
Honored Contributor III
1,214 Views

app4619 wrote:

When you have PRIVATE in a module header all entities in any modules that are inclued with USE automatically become private. Is they any way of modifying this behaviour so that public entifities in the sub module are still public?

app4619,

Are you modifying the "stuff" from module B in module A?  For example, extending a type, replacing a procedure, etc.?  If yes, I believe you need to declare the access specifier in A.

Now your example code doesn't imply any modification of "stuff" from B within A.

In that case, why can't you write your code like this?  It would make it much easier to read the code i.e., understand what comes from which module plus you should get the functionality you want.

[fortran]

PROGRAM fred

 

   USE A, ONLY :  ! Access only the stuff needed from A

   USE B, ONLY :  ! Get the stuff needed from B

 

   IMPLICIT NONE

  

   ! do stuff

  

END PROGRAM fred

 

MODULE A

 

   USE B, ONLY : ! Get only the stuff needed from B

  

   IMPLICIT NONE

 

   !.. Private by default

   PRIVATE

  

   !.. Stuff that needs to be public, apply the attribute

   !   on type declaration statements

   TYPE(MyType), PUBLIC :: MyOneStuff

   .

   . 

  

END MODULE A

 

MODULE B

 

   !.. Private by default

   PRIVATE

 

   IMPLICIT NONE

  

   !.. Stuff that needs to be public, apply the attribute

   !   on type declaration statements

   TYPE(MyType), PUBLIC :: MyOneStuff

   .

   . 

  

END MODULE B 

[/fortran]

0 Kudos
andrew_4619
Honored Contributor III
1,214 Views

I would agreed with your method but in this case the code snipped was an oversimplification of reality. Module A was infact my toolkit of high end 3D graphics utitifies based on Opengl (gl & Glu), windows sdk & GLEW (opengl extension wrangler) so module B is actually B,C,D,E... with many hundreds of public parameters constants and interfaces. In my apllication for simplicity I only wanted the USE module for easy code maintainability. 

In this case the IanHs suggestion if making a top level module that is default PUBLIC and then have all the other modules as USE with whaever is internally deffined public/private is the best soluition for me I think, but I havn't made a descision as yet.

0 Kudos
Steven_L_Intel1
Employee
1,214 Views

I've seen a new feature request to the Fortran standards committee for this sort of "pass through PUBLIC" option, but it was not accepted for the next standard (which is being narrowly restricted on new features.)

0 Kudos
Reply