- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a subroutine that uses an array defined elsewhere in the program and accessed through a USE statement. I have found that if the same array name is defined in two different modules and accessed by two USE statements then no warning is flagged up. This is the case even when the arrays (both with the same name) are defined with different sizes. This may be a result of my programming style in which I have assumed that the compiler would protect against such issues rather than explicitly protect myself. Intel's advice would be appreceated. Thanks, ACAR.
Link Copied
18 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When you say "accessed by two USE statements" you mean that you have two USEs that make names from those modules visible. This is legal as long as you don't actually reference the array in that program unit. If you do, you will get an error. If you have a test case that shows otherwise, please let us know.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ACAR,
Examine the following program
Jim Dempsey
Examine the following program
[fortran]module once real :: A(100) end module once module twice real :: A(200) end module twice program UseTwice call one call two call onetwo end program UseTwice subroutine one() use once write(*,*) size(A) end subroutine one subroutine two() use twice write(*,*) size(A) end subroutine two subroutine onetwo() use once, Aone => A use twice, Atwo => A write(*,*) size(Aone) write(*,*) size(Atwo) end subroutine onetwo [/fortran]
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The following is a model of what I think is being allowed:
MODULE MODA
REAL(8)::BORIS(2,2)
END MODULE
MODULE MODB
REAL(8)::BORIS(2,5)
END MODULE
SUBROUTINE TEST
USE MODA
USE MODB
RETURN
END
Two modules somewhere or other in my application with the same variable name (BORIS). The subroutine USEs these two modules and seems to allow the fact that both modules contain the same variable BORIS. Is this expected behaviour since?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, that is permitted by the language, as long as subroutine TEST doesn't try to reference BORIS. If I take your example and add a READ of BORIS in TEST, I get this:
t.f90(10): error #6405: The same named entity from different modules and/or program units cannot be referenced. [BORIS]
read (*,*) BORIS
-----------^
It is very common that different modules may declare things of the same name. As long as you don't try to use them, that's fine.
t.f90(10): error #6405: The same named entity from different modules and/or program units cannot be referenced. [BORIS]
read (*,*) BORIS
-----------^
It is very common that different modules may declare things of the same name. As long as you don't try to use them, that's fine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Jim, yes that is one solution to the problem but I was rather hoping I would get some warning or error from the compiler that an ambiguity existed. Perhaps in naivety I had assumed that to be the case.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I should have added an operation to the subroutine using BORIS because that is what I am experiencing in my application - ambiguity being allowed. Actually for the case in question my equivalent to the subroutine TEST doesn't explicitly operate on BORIS, rather it passes it to another subroutine which then operates on BORIS.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If it so much as names BORIS you should get an error. Please show me an example where it doesn't.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You also have to include local variable names
module foo
real :: BORIS(123)
end module foo
module foofoo
real :: BORIS(456)
end module foofoo
subroutine one
real :: BORIS(789)
call test(BORIS) ! local scope
end subroutine one
subroutine two
use foo
call test(BORIS) ! BORIS within foo
end subroutine two
subroutine three
use foofoo
call test(BORIS) ! BORIS within foofoo
end subroutine three
It is not unusual for modules and subroutines to potentially contain conflicting names (e.g. TEMP, X, Y, Z, etc...)
I do not have a newer version of IVF (currently on 11.0.66) so I do not know if the newer versions permit scoping operators, which would permit something like the following:
subroutine four
use foo
use foofoo
call test(foo::BORIS)
call test(foofoo::BORIS)
end subroutine four
*** the above only valid if compiler supports scoping operator
Maybe Steve can comment on scoping operators, as to if present or if considered.
Jim Dempsey
module foo
real :: BORIS(123)
end module foo
module foofoo
real :: BORIS(456)
end module foofoo
subroutine one
real :: BORIS(789)
call test(BORIS) ! local scope
end subroutine one
subroutine two
use foo
call test(BORIS) ! BORIS within foo
end subroutine two
subroutine three
use foofoo
call test(BORIS) ! BORIS within foofoo
end subroutine three
It is not unusual for modules and subroutines to potentially contain conflicting names (e.g. TEMP, X, Y, Z, etc...)
I do not have a newer version of IVF (currently on 11.0.66) so I do not know if the newer versions permit scoping operators, which would permit something like the following:
subroutine four
use foo
use foofoo
call test(foo::BORIS)
call test(foofoo::BORIS)
end subroutine four
*** the above only valid if compiler supports scoping operator
Maybe Steve can comment on scoping operators, as to if present or if considered.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are no "scoping operators" in Fortran.
A local variable does not hide a name made visible from a module - that gets you an error. However, a local variable DOES hide variables that are defined in an outer scope.
A local variable does not hide a name made visible from a module - that gets you an error. However, a local variable DOES hide variables that are defined in an outer scope.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Okay, I've looked in further detail at my code. What I have is not quite what I suggested, it is as follows:
MODULE MODA
USE MODB
REAL(8)::BORIS(2,2)
END MODULE
MODULE MODB
REAL(8)::BORIS(3,3)
END MODULE
SUBROUTINE TEST
USE MODA
RETURN
END
So MODA makes two forms of BORIS available to the routine TEST which does not pick up the ambiguity.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your actual source probably doesn't look like that. If I take your test case and correct it so that MODB is compiled first, I get:
t.f90(6): error #6401: The attributes of this name conflict with those made accessible by a USE statement. [BORIS]
REAL(8)::BORIS(2,2)
---------^
t.f90(6): error #6401: The attributes of this name conflict with those made accessible by a USE statement. [BORIS]
REAL(8)::BORIS(2,2)
---------^
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When I moved the COMMON BLOCKs ofa legacy code to MODULEs and access the variables via USE statements, I did getnumerous error #6401 and error #6405 that STEVE described for the locally declared variables/multiple declarations.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, this opens up a further question Steve. I have numerous module spread around my application all in seperate files. I don't tell the compiler the order of compilation. So maybe this is the issue I am having? This issue harks back to a question I raised about a month ago on managing modules. My application has grown over a number of years and with it my skill at programming. I'm sure I have redundant USE statements in the application but no practical way of eliminating them.
What happens if you compile without modifying my example - perhaps putting the two modules in seperate files?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you are using Visual Studio and have the modules in separate files, they will be compiled in the correct order. As you had the source, the module with the USE was before the module it USEd. What might happen is that if the USEd module had been compiled previously, that earlier definition would be used. Intel's compiler requires that a module be compiled before any USE of it is seen, so if the module and the USE are in the same source, the module must come first. If they are in separate files, as I mentioned earlier, Visual Studio's project dependence analyzer will cause the files to be compiled in the proper order (as long as you don't have circular dependencies.)
Redundant USEs aren't harmful - if you're concerned about this, comment out ones you thing may be unnecessary and see if the source still compiles (and does the right thing.)
Redundant USEs aren't harmful - if you're concerned about this, comment out ones you thing may be unnecessary and see if the source still compiles (and does the right thing.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Okay thanks Steve. I'll ignore redundant USEs if they arn't harmful - I can't face the task of going rount 5000 subroutines with the comment/compile check just at the moment.
With regard to the original question regarding multiple declarations I must admit that I'm baffled. It is certainly happening in my application. It has happened before and I've just ignored it but this time it was blatent since the two instances of the array in question where of different sizes. Its a pity I can't send you my application to help sort this out. Probably best thing is for me to keep a note of this and see if I can find the reason - probably something odd that I'm doing!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Something to keep in mind is that the variables in the different modules are completely independent, even if you use the same name. The actual variable name in the symbol table also includes a reference to the module the variable is in. So it is only when you use two of the modules in the same routine and reference that variable (without explicitly specifying from which module from which to use it) that there is a problem for the compiler to figure out which you mean to access.
They are separate variables even though they have the same name in your mind.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks John. I did assume that to be the case hence my confusion when my routine appeared to be picking up the wrong instance of the same named variable. I think there is something fishy going on here but need some time to sort this out. I'll report back when I find out what on earth I've done!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've run into similar problems where modules are not necessarrily compiled in the correct order, in VS,even though they are in separate files. What sometimes happens is that the compiler will attempt to compile a module and fail because of a syntax error BUT the build will continue and complete with the link. However the link must pick up the older object file of the one that failed. This can cause strange things to happen such as the stepping through debug code will be on lines that don't have any executable code. I've looked for a switch thatwill makea build sequence in VSstop once an error has occured (I used to assume this was always the case).
PS I don't think this is the cause of my problem in my recent thread about the strange debug behaviour.
PS I don't think this is the cause of my problem in my recent thread about the strange debug behaviour.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page