- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I'm using Intel Visual Fortran 11.1.065 [IA-32].
When I have following code in two different files with /warn:interfaces switched on
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(2): error #6552: The CALL statement is invoking a function subprogram as a subroutine. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(2): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(3): error #6552: The CALL statement is invoking a function subprogram as a subroutine. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(4): error #6552: The CALL statement is invoking a function subprogram as a subroutine. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(4): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(5): error #6552: The CALL statement is invoking a function subprogram as a subroutine. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(5): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
When I add USE SUB__genmod after SUBROUTINE TESTSUB
I get following correct messages:
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(3): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(5): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(6): error #6285: There is no matching specific subroutine for this generic subroutine call.
Why does the use statement change the messages? Doesn't the switch /warn:interfaces imply a USE for all modules found in the module directory?
When I have following code in two different files with /warn:interfaces switched on
[fortran] MODULE SUB__genmodI get following unexpected messages:
INTERFACE SUB
SUBROUTINE SUB1(I)
INTEGER(2) I
ENDSUBROUTINE
SUBROUTINE SUB2
REAL(4) R
ENDSUBROUTINE
SUBROUTINE SUB3(I)
INTEGER(8) I
ENDSUBROUTINE
ENDINTERFACE
ENDMODULE SUB__genmod
SUBROUTINE TESTSUB
CALL SUB(1)
CALL SUB(1.)
CALL SUB(1.D0)
CALL SUB(" ")
END
[/fortran]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(2): error #6552: The CALL statement is invoking a function subprogram as a subroutine. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(2): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(3): error #6552: The CALL statement is invoking a function subprogram as a subroutine. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(4): error #6552: The CALL statement is invoking a function subprogram as a subroutine. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(4): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(5): error #6552: The CALL statement is invoking a function subprogram as a subroutine. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(5): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
When I add USE SUB__genmod after SUBROUTINE TESTSUB
I get following correct messages:
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(3): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(5): error #6285: There is no matching specific subroutine for this generic subroutine call. [SUB]
C:\\sw\\wg\\rukon_entw\\testmodulsub.for(6): error #6285: There is no matching specific subroutine for this generic subroutine call.
Why does the use statement change the messages? Doesn't the switch /warn:interfaces imply a USE for all modules found in the module directory?
コピーされたリンク
13 返答(返信)
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
No, it most certainly does NOT imply that.
What /warn:interface does is:
1) Generate a module with an interface block for procedures that are "external" - that is, not CONTAINed in a module or another procedure
2) When a reference is made to a procedure that does not have an explicit interface provided, it looks for the generated interface and compares the call to see if there are any errors
/warn:interface is a diagnostic tool only - it is not a substitute for adding USE or explicit interfaces to your code. It will tell you if you need an explicit interface or if you have an argument mismatch, but it won't "fix" the problem for you.
What /warn:interface does is:
1) Generate a module with an interface block for procedures that are "external" - that is, not CONTAINed in a module or another procedure
2) When a reference is made to a procedure that does not have an explicit interface provided, it looks for the generated interface and compares the call to see if there are any errors
/warn:interface is a diagnostic tool only - it is not a substitute for adding USE or explicit interfaces to your code. It will tell you if you need an explicit interface or if you have an argument mismatch, but it won't "fix" the problem for you.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
So not all MODULE-features are allowed in a *_genmod-file? If you look at my example generics don't always work.
I do such strange things because I've still the same problem I posted some weeks ago.
My project consitst of thousands of FORTRAN files and I would like to work with interfaces but I can not change all FORTRAN files an add hundreds of USE statements in each of thosefiles. So Iautomatically generated interfaces in a global directory andlet them proove by /warn:intefacefor those fortran-filesI have to change.
Now I changed some interfaces to create generics (some of the subroutines can be called with integers or reals or doubles or arrays) which overwrite the automatic generated interfaces in myglobal directory. And this works as long as the first Interface has the same name like the generic. You can proof this by changing SUB1 in the interface of in my example to SUB.
I wondered why I had to do this and thought of a compiler bug. But its clear if *_genmod interfaces are not handled like normal interfaces. I think there is no workaround?
I do such strange things because I've still the same problem I posted some weeks ago.
My project consitst of thousands of FORTRAN files and I would like to work with interfaces but I can not change all FORTRAN files an add hundreds of USE statements in each of thosefiles. So Iautomatically generated interfaces in a global directory andlet them proove by /warn:intefacefor those fortran-filesI have to change.
Now I changed some interfaces to create generics (some of the subroutines can be called with integers or reals or doubles or arrays) which overwrite the automatic generated interfaces in myglobal directory. And this works as long as the first Interface has the same name like the generic. You can proof this by changing SUB1 in the interface of in my example to SUB.
I wondered why I had to do this and thought of a compiler bug. But its clear if *_genmod interfaces are not handled like normal interfaces. I think there is no workaround?
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Generated modules are for "Fortran 77" style external procedures. There's no way that generics can enter into it. You could use generated modules to help you construct real modules, but it isn't a substitute for USE where the language requires it.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Because of the number of subroutines you will understand that writing interfaces and including USE for each subroutine isn't an option for us.
When I told this my colleagues they said, "OK, let's switch back to CVF" (because in CVF you could not link if you called a subroutine with the wrong number of parameters) and "Why do I have to assist the compiler? Why doesn't the compiler assist me?" (because of the USE statements we have to add if we want to avoid wrong parameters in subroutine calls).
My example seems to shows a working solution for our problem. I only have to change the genmod-files for subroutines which are allowed to be called with different parameters. No self written interface is required for all other subroutines. No USE is required. Perfect! Even linking is ok after adding !DEC$ ATTRIBUTES DECORATE,ALIAS:"SUB" ::SUB1 and !DEC$ ATTRIBUTES DECORATE,ALIAS:"SUB" ::SUB2.
So is it right to say "There's no way that generics can enter into it"?
Or do I really have to abandon parameter checking (or switch back to CVF)!
Thanks for your patience.
When I told this my colleagues they said, "OK, let's switch back to CVF" (because in CVF you could not link if you called a subroutine with the wrong number of parameters) and "Why do I have to assist the compiler? Why doesn't the compiler assist me?" (because of the USE statements we have to add if we want to avoid wrong parameters in subroutine calls).
My example seems to shows a working solution for our problem. I only have to change the genmod-files for subroutines which are allowed to be called with different parameters. No self written interface is required for all other subroutines. No USE is required. Perfect! Even linking is ok after adding !DEC$ ATTRIBUTES DECORATE,ALIAS:"SUB" ::SUB1 and !DEC$ ATTRIBUTES DECORATE,ALIAS:"SUB" ::SUB2.
So is it right to say "There's no way that generics can enter into it"?
Or do I really have to abandon parameter checking (or switch back to CVF)!
Thanks for your patience.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
You can do what CVF did by just using the option /iface:cvf with the Intel compiler (there are other variations on this, as well).
The "OK, let's switch back to CVF" is not good advice. While the Stdcall name decoration is better than nothing, all it does is to check if the byte count sum of all the arguments match.
For example, the following program has one instance of calling with wrong parameters that CVF 6.6 will not catch with df /4Yb:
The "OK, let's switch back to CVF" is not good advice. While the Stdcall name decoration is better than nothing, all it does is to check if the byte count sum of all the arguments match.
For example, the following program has one instance of calling with wrong parameters that CVF 6.6 will not catch with df /4Yb:
[fortran]program abuser integer i real x i=3 x=4.0 call sub(i,x) write(*,*)i,x call sub(x,i) write(*,*)i,x end program abuser subroutine sub(i,x) integer i real x x=x+i return end subroutine sub[/fortran]There is no substitute for knowing the implications of how code is written, tested and used, and no easy way out of taking the time needed for locating and removing bugs in large codebases.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
You and your colleague misunderstand the situation.
Intel Fortran goes much further than CVF did in diagnosing errors in calls. That's what /warn:interface is for. Unlike CVF's limited checking (it could detect argument type mismatches within a single source file only), /warn:interface is global across your application and detects many kind of argument mismatches. "Going back to CVF" will get you LESS checking, not more.
However, you seem to ALSO want the compiler to correct your programming errors. CVF certainly won't do that, and neither will Intel Fortran. With both compilers, if you will be using languge features that require an explicit interface, there is no substitute for arranging your code so that such an interface is provided and visible. Usually the simplest way is to put all procedures in modules, but there are other options.
If you DO provide explicit interfaces for all routines, then the compiler can also check for errors, but not really any more than /warn:interface will do.
Intel Fortran goes much further than CVF did in diagnosing errors in calls. That's what /warn:interface is for. Unlike CVF's limited checking (it could detect argument type mismatches within a single source file only), /warn:interface is global across your application and detects many kind of argument mismatches. "Going back to CVF" will get you LESS checking, not more.
However, you seem to ALSO want the compiler to correct your programming errors. CVF certainly won't do that, and neither will Intel Fortran. With both compilers, if you will be using languge features that require an explicit interface, there is no substitute for arranging your code so that such an interface is provided and visible. Usually the simplest way is to put all procedures in modules, but there are other options.
If you DO provide explicit interfaces for all routines, then the compiler can also check for errors, but not really any more than /warn:interface will do.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Hello mecej4,
add call sub(i) or call sub(i,x,0) after the first correct call to suband you will see that the programm compiles and links without any error (without flag /warn:interfaces) but you will have a runtime error when you reach the wrong call.
With CVF you could not link this program (as far as I can remember). Except this special case (which caused a lot of trouble formy colleagues what explains their love to CVF) I'm sure IVF is much better in error checking than CVF. Now I'm looking for a way to avoid such problems. The best way would be using interfaces which would help us to avoid much more errors (that's becauseI love them). Because of the number of subroutines we use I have to find a way to generate and check them automatically. This cause the problems I described here.
add call sub(i) or call sub(i,x,0) after the first correct call to suband you will see that the programm compiles and links without any error (without flag /warn:interfaces) but you will have a runtime error when you reach the wrong call.
With CVF you could not link this program (as far as I can remember). Except this special case (which caused a lot of trouble formy colleagues what explains their love to CVF) I'm sure IVF is much better in error checking than CVF. Now I'm looking for a way to avoid such problems. The best way would be using interfaces which would help us to avoid much more errors (that's becauseI love them). Because of the number of subroutines we use I have to find a way to generate and check them automatically. This cause the problems I described here.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Hi Steve,
I'm sure you are absolutly right. Except the very special case of calling a subroutine with a different number of arguments in the same program unit (likeI discussed with mecej4) I'm sure that IVF is the right choice.
I'm simply looking for a way to use and check interfaces with minimal charges. /gen-interfaces and /warn:interfacesare a nearly perfect solution. Interfaces are generated automatically and they are automatically visible without any change to the source code.
But some of my source files (In my case let me say some hundred) require a special interface which can not be build with /gen-interfaces. So I have to write these interfaces myself. No Problem. But how to make them visible to thousends of other subroutines?
You say I have to add use statements to them. But this requires that I have to add hundreds of USE statements to thousends of subroutines. OK, I can do this by a script. Not a great problem. But each time I change a Subroutine afterwards and add or remove calls I have to know wich calls require a USE and which one don't! Nearly impossible in my case.
So myquestion is simply: How can I make self written Interfaces automatically visible?
This is done with the automatic generated Interfaces with switches /gen-intefaces/warn-interfaces, why not with self written interfaces?
My first Attempt was to overwrite then Interfaces generated with switch /gen-interfaces. This seems to work (with some restrictions) but you say: "Don't do that". Any other idea?
I'm sure you are absolutly right. Except the very special case of calling a subroutine with a different number of arguments in the same program unit (likeI discussed with mecej4) I'm sure that IVF is the right choice.
I'm simply looking for a way to use and check interfaces with minimal charges. /gen-interfaces and /warn:interfacesare a nearly perfect solution. Interfaces are generated automatically and they are automatically visible without any change to the source code.
But some of my source files (In my case let me say some hundred) require a special interface which can not be build with /gen-interfaces. So I have to write these interfaces myself. No Problem. But how to make them visible to thousends of other subroutines?
You say I have to add use statements to them. But this requires that I have to add hundreds of USE statements to thousends of subroutines. OK, I can do this by a script. Not a great problem. But each time I change a Subroutine afterwards and add or remove calls I have to know wich calls require a USE and which one don't! Nearly impossible in my case.
So myquestion is simply: How can I make self written Interfaces automatically visible?
This is done with the automatic generated Interfaces with switches /gen-intefaces/warn-interfaces, why not with self written interfaces?
My first Attempt was to overwrite then Interfaces generated with switch /gen-interfaces. This seems to work (with some restrictions) but you say: "Don't do that". Any other idea?
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
I do not see the problem about "wich calls require a USE and which one don't!".
When I want to use a Windows API function I add USE DFWIN (or USE IFWIN). This basically contains the following:
MODULE DFWIN
use advapi32
use comdlg32
use dfwbase
use gdi32
use kernel32
use lz32
use mpr
use shell32
use user32
use version
use winmm
use winspool
use wsock32
END MODULE DFWIN
each 'USE DFWIN' therefore making available ALL the Windows API function/subroutine interfaces that may be needed by the compiler, which then finds the one it needs to match the function or routine that I call in my program.
So you should make up a module containing the (possibly generated) interfaces to all your functions and routines, in the manner shown above, and USE it in ALL your subprograms, just in case, so that at least it will be available to the compiler when you add a call. Deleting the call is of no consequence. You can keep the USE statement even if there are no calls to subprograms whose interface blocks are included in the module USEd.
P.S. I am not sure if there is a significant compile time penalty including a USE when there is no 'need' for it. I will leave that question for others to consider.
When I want to use a Windows API function I add USE DFWIN (or USE IFWIN). This basically contains the following:
MODULE DFWIN
use advapi32
use comdlg32
use dfwbase
use gdi32
use kernel32
use lz32
use mpr
use shell32
use user32
use version
use winmm
use winspool
use wsock32
END MODULE DFWIN
each 'USE DFWIN' therefore making available ALL the Windows API function/subroutine interfaces that may be needed by the compiler, which then finds the one it needs to match the function or routine that I call in my program.
So you should make up a module containing the (possibly generated) interfaces to all your functions and routines, in the manner shown above, and USE it in ALL your subprograms, just in case, so that at least it will be available to the compiler when you add a call. Deleting the call is of no consequence. You can keep the USE statement even if there are no calls to subprograms whose interface blocks are included in the module USEd.
P.S. I am not sure if there is a significant compile time penalty including a USE when there is no 'need' for it. I will leave that question for others to consider.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
rwg,
If you are writing generic interfaces, then you MUST provide an explicit interface. No way around that. Don't confuse this matter with argument checking - you get that better in Intel Fortran than with CVF. Generated interfaces are not a substitute for required explicit interfaces. Generated interfaces are NOT a replacement for USE - they are for error checking only.
We do have an open feature request for what I call "auto-include" that would help you here - you'd compile with an option that would automatically include a specified file in each program unit where a USE could appear. This is not yet implemented, however.
You do not have to "add hundreds of USE statements". Just create a module with your generic interfaces and add a single USE where that generic is used. If you have more than one generic, they all go in the same module. Don't be confused by generated interfaces creating distinct modules for each procedure - that's just a side-effect of the way this feature works. Learn how to use modules well. If you are calling procedures that don't require an interface, you don't need to supply one.
If you are writing generic interfaces, then you MUST provide an explicit interface. No way around that. Don't confuse this matter with argument checking - you get that better in Intel Fortran than with CVF. Generated interfaces are not a substitute for required explicit interfaces. Generated interfaces are NOT a replacement for USE - they are for error checking only.
We do have an open feature request for what I call "auto-include" that would help you here - you'd compile with an option that would automatically include a specified file in each program unit where a USE could appear. This is not yet implemented, however.
You do not have to "add hundreds of USE statements". Just create a module with your generic interfaces and add a single USE where that generic is used. If you have more than one generic, they all go in the same module. Don't be confused by generated interfaces creating distinct modules for each procedure - that's just a side-effect of the way this feature works. Learn how to use modules well. If you are calling procedures that don't require an interface, you don't need to supply one.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
What I am looking for is not only an "auto-include".I would like to have something you can call"auto-interface". This creates an interface-file for each Subroutine definition (like /wan:interface or /gen-interface does, but even if the subroutine has an explicit interface!). During compilation of files the compiler searches these interface-files for each subroutine call (like /warn-interface) and really uses then (not only for diagnostic like it is done now).
If you use "auto-interface" there is no need to write explicit interfaces even if FORTRAN requires a interface (except for generics or other things which can not be extracted from a pure subroutine definition) and no need for a USE statement because the compiler generates and uses everything he needs.
This is something like putting all subroutines in one module. The compiler 'sees' all he needs and uses it.
If you use "auto-interface" there is no need to write explicit interfaces even if FORTRAN requires a interface (except for generics or other things which can not be extracted from a pure subroutine definition) and no need for a USE statement because the compiler generates and uses everything he needs.
This is something like putting all subroutines in one module. The compiler 'sees' all he needs and uses it.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
You mention putting everything into the one module - this might sound silly (and probably is!) - but is that worth trying? I've done it before as a step in F77 to F95 migration. I recall a lot of mindless cut and pasting of FUNCTION and SUBROUTINE to go after the END statements, and then putting together a whole lot of include statements to pull all the bits in (both stages could be scripted). I then had to resolve some name clashes (such as variables and functions with the same name) and put one USE statement in the main program. Ta-da - "auto-interface"!
I had super-module vs lots of external subprograms as separate projects (with mostly the same source files) in VS at one stage.
There are probably compiler limits on how big a module can be, but if you hit them you can always try and divide things into two or three big modules. That division begins to reflect the way the program should be broken up/grouped anyway...
I had super-module vs lots of external subprograms as separate projects (with mostly the same source files) in VS at one stage.
There are probably compiler limits on how big a module can be, but if you hit them you can always try and divide things into two or three big modules. That division begins to reflect the way the program should be broken up/grouped anyway...
[fxfortran] MODULE pretty_much_everything CONTAINS INCLUDE 'file1.for' INCLUDE 'file2.for' INCLUDE 'somedirectoryfile3.for' ... END MODULE pretty_much_everything [/fxfortran]
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Hi IanH,
thanks for your reply. I think putting everything in one module can only help if your project is not to big.
We have to manage about 9000 Source files to build one executable. I remember that we even split one or two of those 9000 files because they were to big to get compiled. So putting all together will not be a solution for my problem.
As you mentioned another problem would be that referencec to thismega module will take a long time. The compiler has to search the whole module to find interfaces. With "auto-interface" this is no problembecause the compiler would find the suitable interface by the filename (subroutine-name + _genmod.mod). Also with "auto-interfaces" you could add or remove subroutines without changing your megamodule or includes.
But I think your solution is a good idea for smaller projects an helps to port vom F77 to F95.
thanks for your reply. I think putting everything in one module can only help if your project is not to big.
We have to manage about 9000 Source files to build one executable. I remember that we even split one or two of those 9000 files because they were to big to get compiled. So putting all together will not be a solution for my problem.
As you mentioned another problem would be that referencec to thismega module will take a long time. The compiler has to search the whole module to find interfaces. With "auto-interface" this is no problembecause the compiler would find the suitable interface by the filename (subroutine-name + _genmod.mod). Also with "auto-interfaces" you could add or remove subroutines without changing your megamodule or includes.
But I think your solution is a good idea for smaller projects an helps to port vom F77 to F95.
