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

Module members surprisingly shared through USE statement

vvnurmi
Beginner
1,745 Views

The example below demonstrates how the memberMY_INT of module A are visible in the main program that doesn't explicitly USE module A. All that is needed is that the program contains statement USE B, and module B contains statement USE A.

Is this as it should be? I find it surprising. In a scenario where I have a low-level module A that module B uses for some dirty implementation details, the low-level stuff from A flows to even higher-level program units unless I pay attention in each module and program to make default visibility PRIVATE. Why should it be so that all the modules that module B uses, are by default used also by those who use module B?

MODULE A IMPLICIT NONE INTEGER :: MY_INT = 42 END MODULE A MODULE B USE A
IMPLICIT NONE
! PRIVATE ! uncomment this line to make MY_INT not visible to whoever uses this module
END MODULE B PROGRAM MODULEUSETEST USE B IMPLICIT NONE WRITE(*,*) MY_INT ! compiles and prints "42" END PROGRAM MODULEUSETEST

0 Kudos
5 Replies
mecej4
Honored Contributor III
1,745 Views
Is this as it should be? I find it surprising.

Of course it is. A perusal of the Fortran documentation, or textbooks on modern Fortran, would remove the surprise.

USE means "use as prescribed by the rules". It cannot mean "use only those things that I want and leave out those that I don't want but, as I am too busy to specify them in writing, figure it out yourself." This is so, just as IMPLICIT NONE implies that within its scope all undeclared variables are illegal, even the name/prefix BOOL that I always use for my logical variables.

Compilers are not yet mind readers, and I am content with that state of affairs.
0 Kudos
IanH
Honored Contributor III
1,745 Views
I guess in order for a module to be useful, it needs to have at least one publicly accessible entity. That, plus the fact that modules sort of grew out of include files, tends to point towards public accessibility being the default. Once you are there, having use associated entities somehow behave differently to other entities in the module (in the absence of some mechanism that specifies accessibility for all entities picked up from a module - say via attributes on the use statements themselves) would get confusing and I can think of some cases where it could create maintenance headaches.

You could also add a PRIVATE :: MY_INT statement to module B.

Most of my modules have private accessibility as the default. If you are trying to hide implementation this is the easiest thing to do anyway. Of course, until submodules are here there's nothing to stop the inquisitive client programmer from putting USE A into the main program and accessing MY_INT that way.
0 Kudos
vvnurmi
Beginner
1,745 Views

Of course it is. A perusal of the Fortran documentation, or textbooks on modern Fortran, would remove the surprise.

I failed to find an exhaustive explanation of this with moderate effort from my Fortran textbook. Knowing now that this is an intended feature of Fortran, there is no surprise any longer.

I originally thought Fortran's USE to behave more like "using" in C# or "import" in Java, importing symbols only for use at the local context but not any further. This serves as a good lesson to find out the facts before assuming anything :-).

Thanks for the help.

0 Kudos
Les_Neilson
Valued Contributor II
1,745 Views
It is all too easy to "transfer" our knowledge of one language over to another. Some time ago a colleague (used to programming in C)was struggling to debug some code because he came across CHARACTER*(*) X and thought that X was some kind of C pointer to type char or possibly a pointer to pointer to char.
Ioccasionally make the mistake of writing Fortran syntax (e.g. comments at the end of a line) in C code I'm working on - it makes for interesting compiler messages :-)

Les
0 Kudos
mecej4
Honored Contributor III
1,745 Views
Section 5.15 of Fortran 95/2003 explained by Metcalf, Reid and Cohen, Oxford, 2005, says:

--------------------------------
5.15 Scope of Names
..
A use statement of the form

use module-name

is regarded as a re-declaration of all the module entities inside the local scoping unit, with exactly the same names and properties.
---------------------------------

One large package in Fortran that I saw a few months ago made effective use of the properties of modules in the following way.

There was a module-A which contained declarations of all variables which were shared across subprograms in the package. However, no subprogram USEd module-A directly.

Instead, there were modules B1, B2, B3,.., all of which USEd module-A, but used the use module-A, only: ... in combination with private applied to the variables brought in this way. Thus, the programmer provided controlled access to only those variables that were actually needed in each subprogram, avoiding unwanted exposure of the other variables in module-A.

The subprograms, in turn, USEd modules B1, B2, ...., thus gaining access to only those parts of module-A that they were entitled to.
0 Kudos
Reply