Variable declarations in Modules

Variable declarations in Modules

In the following code example the compiler indicates a name conflict in example 1 but not in example 2. Is this expected behaviour? What effect might it have on code compiled in similar style to example 2 regarding the actual variable A? Should the global variable A be updated even though a local variable will the same name is defined? In other words if the user mistakenly uses a variable name that also exists in the module as global variable this global variable may be modified (wrongly) and be difficult to track down in the debugger which will display the local value unless testlib::A is entered in a watch window.

module testlib
implicit none
integer :: A = 1
end module

module ex1

contains
subroutine Ex1Sub(v)

! Declare Module inside contained procedure
use testlib
implicit none
integer,intent(out) :: v

integer :: A ! Compiler flags name conflict
integer :: i

A = 0
do i = 1 , 4
A = A + 1
enddo
v = A
end subroutine
end module

module ex2
! Declare Module Above contained procedures
use testlib

contains
subroutine Ex2Sub(v)

implicit none
integer,intent(out) :: v

integer :: A ! Compiler does NOT flag up name conflict
integer :: i

A = 0
do i = 1 , 4
A = A + 1
enddo
v = A

end subroutine
end module

I prefer to declare all modules at the top of a higher level module rather than individually in each internal procedure but this may lead on to bugs that are hard to detect as debugger may not shown the contents of the correct variable and the global module variable may get modified within a procedure by mistake.  Can anybody explain what is really happening here and what is the best practice to adopt.

Thanks

 

Steve

4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Steve Sutcliffe,

Can you please use {fortran} {/fortran} (replace curly brackets with square ones) to syntax highlight your code?  It'll much easier for others to read it.

Fyi, I open a Word document, set the font to Courier New, paste the code in there, do any clean-up formatting as needed, and then copy it into the Clipboard.  I then use the "Paste the Word" option in the forum Comment section (3rd from right with the clipboard icon with a W in it) to paste into this forum and make sure to syntax highlighting.  I find the code looks much cleaner this way.

Cheers,

 

Declaring A as local within the subroutine will cause a name conflict, being as you have declared two variables of the same type and the same name in the same scope.  Setting the use clause at module level is a difference in scope.  At module level, A is from testlib with the local A within the subroutine being at that level of scope.

Options you have would be to either change the names of the local variables (could be a time sink) or set a rename in the use clause, as in

use testlib, B => A

 

The rules for use association and host association are different. In the first case, A is made visible by use-association, hiding the host-associated name, But you then declare A locally and this is not allowed when the same name is use-associated.

In the second case you have host association and there the local declaration hides the outer one. Yes, this is a trap for the unwary, but that's how the language is defined.

Retired 12/31/2016

Leave a Comment

Please sign in to add a comment. Not a member? Join today