- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am using a module within a module and expected to get a compilation conflict error for variable IB in the sample shown below, but did not. I looked in the forum and the problem seems similar to this recent post, but is not quite the same: https://community.intel.com/t5/Intel-Fortran-Compiler/Scope-of-USE-statement-in-an-INTERFACE-block/td-p/1252444/jump-to/first-unread-message
If IB is declared in subroutine DYN_IN, program compiles but IB declared within INPUT_DATA seems to be ignored (IB within main program remains 0). If IB is not declared in DYN_IN, program functions as expected and IB becomes 1 in the main program. Is this a bug or am I making an error? Thank you!
PROGRAM MODTEST
USE INPUT_DATA
USE DYNAMICS_DATA
IMPLICIT NONE
IB = 0
CALL DYN_IN
STOP
END
MODULE INPUT_DATA
INTEGER(4) IB
END MODULE INPUT_DATA
MODULE DYNAMICS_DATA
IMPLICIT NONE
INTERFACE
MODULE SUBROUTINE DYN_IN
END SUBROUTINE DYN_IN
END INTERFACE
END MODULE DYNAMICS_DATA
SUBMODULE (DYNAMICS_DATA) DYNAMICS_SUBMOD
USE INPUT_DATA
IMPLICIT NONE
CONTAINS
MODULE SUBROUTINE DYN_IN
IMPLICIT NONE
INTEGER(4) IB ! should this be an error due to conflict with INPUT_DATA?
IB = 1
END SUBROUTINE DYN_IN
END SUBMODULE DYNAMICS_SUBMOD
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would expect that IB within DYN_IN would be a local variable and that you would have no access to IB in the module.
Local variables with the same name as a global entity take precedence.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please consider the following line of thought.
Suppose there was no declaration of the variable IB in DYN_IN. Would the variable still be available in the module subroutine because of host association or use association? IB is available by use association in the submodule that contains DYN_IN. Inside the contained subroutine DYN_IN, however, it is available by association from the immediate host, i.e., the submodule.
Local variable declarations override variables of the same name that are host-associated. Local variable declarations come into conflict with variables of the same name that are use-associated.
It would be instructive to move USE INPUT_DATA from the submodule into DYN_IN and try compiling the modified code. The compiler may alert you to the conflict between use-associated variables and the local variable.
Things may become more complicated if, instead of simple variables as in this example, we have some variables that have the pointer attribute.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the great explanation. I had started in the habit of sometimes placing the USE statement one time in the specification portion of module above the CONTAINS statement rather than repeating it multiple times in perhaps several dozen subroutines below. I can see that doing this can cause possible unexpected adverse behavior without error or warning in the compile. By moving the USE statement within the subroutine I did get the error that I was looking for, so I will proceed in that fashion.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Bill1 wrote:
.. I had started in the habit of sometimes placing the USE statement one time in the specification portion of module above the CONTAINS statement rather than repeating it multiple times in perhaps several dozen subroutines below. I can see that doing this can cause possible unexpected adverse behavior without error or warning in the compile. By moving the USE statement within the subroutine I did get the error that I was looking for, so I will proceed in that fashion.
@Bill1 ,
What you've decided as per quoted comment above can prove rather onerous and limiting with library code, especially as the code tries to achieve more complex tasks.
I suggest you look into ", ONLY : " clause with your USE statements (look at only-list in the link below):
And also study the IMPORT facility introduced starting with Fortran 2018 and the ONLY clause with it also:
The above combination can provide you with better control of associated entities (whether via use-association or host-association) and reduce "namespace pollution" and "collisions" as referred to in programming parlance.
Here's a variant of your code for a hypothetical scenario to show these options:
MODULE INPUT_DATA
INTEGER(4) IB
real :: x
END MODULE INPUT_DATA
MODULE DYNAMICS_DATA
IMPLICIT NONE
INTERFACE
MODULE SUBROUTINE DYN_IN
END SUBROUTINE DYN_IN
END INTERFACE
END MODULE DYNAMICS_DATA
SUBMODULE (DYNAMICS_DATA) DYNAMICS_SUBMOD
USE INPUT_DATA, only : x !<-- say, access is needed only to x in this submodule
IMPLICIT NONE
CONTAINS
MODULE SUBROUTINE DYN_IN
IMPORT, NONE !<-- say "DYN_IN" is a simple routine and no access to module entities are needed
INTEGER(4) IB
IB = 1
END SUBROUTINE DYN_IN
! Additional procedures which consume 'x' from INPUT_DATA may be contained below
END SUBMODULE DYNAMICS_SUBMOD
PROGRAM MODTEST
USE INPUT_DATA
USE DYNAMICS_DATA
IMPLICIT NONE
IB = 0
CALL DYN_IN
print *, "IB = ", IB, "; expected is 0"
STOP
END
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
And again, I have a Doctor Fortran post that relates to this topic! Doctor Fortran in "Think, Thank, Thunk" - Doctor Fortran (stevelionel.com)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve-
Thanks for all of your insightful help through the years. I have been reading your articles since the CVF days. If Intel is open to user suggestions, I would suggest that the capability for issuing a compiler warning when this host-association conflict occurs would be very helpful, as this can cause erroneous results and be very difficult to track down. When adding MODULES and IMPLICIT NONE into a 70,000 line legacy code application, it is very easy to trip up on this!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have advocated in the past for "usage" warnings in cases where the usage is standard-conforming but might not be what the programmer expects. The case you cite would have to be something the user asked for explicitly, rather than default, as even informational diagnostics for standard code result in complaints to support.
There is no "conflict" here - declaring a local variable that overrides a host-associated variable is something commonly done and is in the language for a good reason. I'd have a hard time justifying any sort of diagnostic for this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Bill1 then adding a USE to an existing code my motto is "only use USE with ONLY" this avoids possible confusions and give clear indication of what the programmer intended and what the routine might modify
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the suggestion. I have been using ONLY, but usually only in situations where I am adding a USE to an existing subroutine and I know specifically why I have added the USE and usually only when there are a few items to list. I figure that this helps document the code as well, indicating the reason why the USE was included. I will look at the IMPORT as well.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page