- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there,
I have an intel fortran project with a subroutine (Lets call it sub A) that calls another subroutine (sub B).
If I add a dummy argument to sub B, clean and rebuild, I get a nice Build succeeded, for example:
[fortran]subroutine A(l, j)
implicit none
integer, intent(in):: l, j
call B(l,j)
endsubroutine[/fortran]
but B now is something like
[fortran]subroutine B(l, j, k)
implicit none
integer, intent(in):: l, j
integer, intent(out):: k
k = l+j
endsubroutine[/fortran]
Is there anyway the compiler can tell me about this?
I have/warn:interfaces and/gen-interfaces as is explained in this thread:
but still nothing!
I haveIntel Visual Fortran Compiler Professional 11.1.048
Any idea? it is really painfull to check by hand!
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Short answer - because that's what modules do.
Long answer - when you put a procedure in a module and then 'use' that module in another scope, then the procedure automatically gains in that other scope what is known as an explicit interface. Practically this means that the compiler must have compiled the source file containing the module before it sees the USE statement, consequently the compiler knows everything about how the procedure should be called when it see the call, consequently it can check that the right arguments have been provided.
("Guaranteed" in my example was a bit strong - I thought the standard required checking, but I might have been wrong. I suspect though, that if a compiler didn't check a call against an explicit interface then most compiler vendors would regard that as a compiler bug.)
If you use external subprograms, as you were originally doing, then there's no guarantee that the source for subroutine B will be compiled before the call, consequently there's no guarantee that the compiler can check the call.
(This lack of required compilation ordering with external subprograms is important in a few case, outside of those cases all procedures should either be module procedures or internal procedures.)
Thread safety is an orthogonal issue to use of modules. You can create thread-unsafe code without using modules, you can create thread-safe code using modules.
(There are multiple ways in which a program can be multi-threaded (automatic parallelization, coarrays, openmp, native threads...) - particularly when you start getting towards the end of that list (the stackoverflow example you link to is at the native thread level) then the whole program's design needs to be mindful of thread safety. Other traditionally non-threaded languages have exactly the same issues.)
Long answer - when you put a procedure in a module and then 'use' that module in another scope, then the procedure automatically gains in that other scope what is known as an explicit interface. Practically this means that the compiler must have compiled the source file containing the module before it sees the USE statement, consequently the compiler knows everything about how the procedure should be called when it see the call, consequently it can check that the right arguments have been provided.
("Guaranteed" in my example was a bit strong - I thought the standard required checking, but I might have been wrong. I suspect though, that if a compiler didn't check a call against an explicit interface then most compiler vendors would regard that as a compiler bug.)
If you use external subprograms, as you were originally doing, then there's no guarantee that the source for subroutine B will be compiled before the call, consequently there's no guarantee that the compiler can check the call.
(This lack of required compilation ordering with external subprograms is important in a few case, outside of those cases all procedures should either be module procedures or internal procedures.)
Thread safety is an orthogonal issue to use of modules. You can create thread-unsafe code without using modules, you can create thread-safe code using modules.
(There are multiple ways in which a program can be multi-threaded (automatic parallelization, coarrays, openmp, native threads...) - particularly when you start getting towards the end of that list (the stackoverflow example you link to is at the native thread level) then the whole program's design needs to be mindful of thread safety. Other traditionally non-threaded languages have exactly the same issues.)
Link Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How are you compiling the program? Subroutine A needs to be able to see the interface for Subroutine B at compile time for warn interfaces find the problem. If the subroutines are compiled separately and subroutine A is compiled before subroutine B, theproblem will not be detected.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I go to Build->Build Solution
Both subroutines are in the same project and solution.
Does that answer your question?
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
warn:interfaces does seem to catch this inconsistency with a 12.1 compiler. I ran your program using:
x:\cq\testing>ifort /warn:interfaces a1.f90
Intel Visual Fortran Compiler XE for applications running on IA-32, Version 12.1 Beta Build x
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
a1.f90(5): error #6631: A non-optional actual argument must be present when invoking a procedure with an explicit interface.
call B(l,j)
---------^
compilation aborted for a1.f90 (code 1)
This functionality may have been provided later than the 11.1 compiler. I'd recommend using a newer compiler.
Best!
-Udit
warn:interfaces does seem to catch this inconsistency with a 12.1 compiler. I ran your program using:
x:\cq\testing>ifort /warn:interfaces a1.f90
Intel Visual Fortran Compiler XE for applications running on IA-32, Version 12.1 Beta Build x
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
a1.f90(5): error #6631: A non-optional actual argument must be present when invoking a procedure with an explicit interface.
call B(l,j)
---------^
compilation aborted for a1.f90 (code 1)
This functionality may have been provided later than the 11.1 compiler. I'd recommend using a newer compiler.
Best!
-Udit
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code above was just an example, not my actual case. I sometimes get error #6631, but not always!
Can't use another version of fortran because of: Money, compatibility with abaqus.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you control the source of subroutines A and B, then put B in a module.
(If abaqus is calling B directly (not via A) then you won't be able to do this, but in that case adding arguments to B would also get you into trouble.)
[fortran]module my_module_name implicit none contains subroutine B(l,j,k) integer, intent(in) :: l, j integer, intent(out) :: k k = l + j end subroutine B end module my_module_name subroutine A(l, j) use my_module_name implicit none integer, intent(in):: l, j ! Missing argument error guaranteed to be reported for the following line. call B(l,j) end subroutine A [/fortran]
(If abaqus is calling B directly (not via A) then you won't be able to do this, but in that case adding arguments to B would also get you into trouble.)
[fortran]module my_module_name implicit none contains subroutine B(l,j,k) integer, intent(in) :: l, j integer, intent(out) :: k k = l + j end subroutine B end module my_module_name subroutine A(l, j) use my_module_name implicit none integer, intent(in):: l, j ! Missing argument error guaranteed to be reported for the following line. call B(l,j) end subroutine A [/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks!
But why putting the subroutine in a module will fix my problem?
Also, will I have multihreading issues with this?
My past experience with modules is that they are not thread safe.
Best
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Short answer - because that's what modules do.
Long answer - when you put a procedure in a module and then 'use' that module in another scope, then the procedure automatically gains in that other scope what is known as an explicit interface. Practically this means that the compiler must have compiled the source file containing the module before it sees the USE statement, consequently the compiler knows everything about how the procedure should be called when it see the call, consequently it can check that the right arguments have been provided.
("Guaranteed" in my example was a bit strong - I thought the standard required checking, but I might have been wrong. I suspect though, that if a compiler didn't check a call against an explicit interface then most compiler vendors would regard that as a compiler bug.)
If you use external subprograms, as you were originally doing, then there's no guarantee that the source for subroutine B will be compiled before the call, consequently there's no guarantee that the compiler can check the call.
(This lack of required compilation ordering with external subprograms is important in a few case, outside of those cases all procedures should either be module procedures or internal procedures.)
Thread safety is an orthogonal issue to use of modules. You can create thread-unsafe code without using modules, you can create thread-safe code using modules.
(There are multiple ways in which a program can be multi-threaded (automatic parallelization, coarrays, openmp, native threads...) - particularly when you start getting towards the end of that list (the stackoverflow example you link to is at the native thread level) then the whole program's design needs to be mindful of thread safety. Other traditionally non-threaded languages have exactly the same issues.)
Long answer - when you put a procedure in a module and then 'use' that module in another scope, then the procedure automatically gains in that other scope what is known as an explicit interface. Practically this means that the compiler must have compiled the source file containing the module before it sees the USE statement, consequently the compiler knows everything about how the procedure should be called when it see the call, consequently it can check that the right arguments have been provided.
("Guaranteed" in my example was a bit strong - I thought the standard required checking, but I might have been wrong. I suspect though, that if a compiler didn't check a call against an explicit interface then most compiler vendors would regard that as a compiler bug.)
If you use external subprograms, as you were originally doing, then there's no guarantee that the source for subroutine B will be compiled before the call, consequently there's no guarantee that the compiler can check the call.
(This lack of required compilation ordering with external subprograms is important in a few case, outside of those cases all procedures should either be module procedures or internal procedures.)
Thread safety is an orthogonal issue to use of modules. You can create thread-unsafe code without using modules, you can create thread-safe code using modules.
(There are multiple ways in which a program can be multi-threaded (automatic parallelization, coarrays, openmp, native threads...) - particularly when you start getting towards the end of that list (the stackoverflow example you link to is at the native thread level) then the whole program's design needs to be mindful of thread safety. Other traditionally non-threaded languages have exactly the same issues.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks!
I suppose I will do one module for each subroutine.
Best
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Instead consider going through your source and grouping related procedures (particularly from the point of view of how they are used) together into a module. Having lots and lots of "little" modules (each with one subroutine) just creates complexity without any benefit.
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