- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
USE IFPORT
IRETURN = RUNQQ ('AnyExec.exe', '-ComlineParam')
IF (IRETURN == -1) PRINT *, 'Application failed'
IF (IRETURN /= -1) PRINT *, 'Application succeeded')
Say that AnyExec.exe does not exist in any searchable path--or say it is not on the computer at all. The function will then return -1, as it should, which can be tested for "application failed". Fine and dandy.
But suppose that someone stupidly (!) forgets to include USE IFPORT. I would expect to get a linker error (unresolved reference), or at least a run time error. But my program runs merrily, returning a seemingly random number from RUNQQ. Testing this value (which is NOT -1), my program happily reports that the application ran successfully.
Needless to say this failed reporting can cause embarassing problems. Why doesn't the compiler or linker report a problem? (and yes I know that EXPLICIT NONE would have helped, but that's another story...)
Link Copied
- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After looking at this again, this "problem" (in my mind) exists because RUNQQ is a function, not a subroutine. If a subroutine, it would be invoked using CALL RUNQQ() and the CALL would enable the linker to flag it as an unresolved external. But invoked as a function, without the USE statement, the compiler can't tell RUNQQ() apart from any other array variable.
As an old-time (DOS) programmer who is struggling with modern (Windows) coding, I am still getting used to the notion of relying so heavily on functions instead of subroutines. To me, invoking procedures using CALL is much more descriptive than just stating the procedure name (as a function). Apparently, it would be much more descriptive to the compiler and linker also. So invoking as a function destroys some of the checking that would be enjoyed if invoking as a subroutine.
Comments?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Intel Fortran does have a feature, Generated Interface Checking, that can detect issues when there are mismatches with your own functions and subroutines, but it doesn't have the information on library routines to check. While we could add a set of generated interfaces for the library routines, there are hundreds of them and some name conflicts which could lead to false errors. If one could turn back the clock, the better choice would be to give the library routines "decorated" names with a prefix different from their Fortran names, so you'd get linker errors if you didn't declare them properly. But for many of these, especially the "portability" routines, they are intended to be called without explicit declaration so this wouldn't work.
My advice is to get in the habit of using IMPLICIT NONE everywhere, adding it where it is missing in your code. Yes, it will mean more work for you, but will save you pain in the long run.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What I'd like to clarify is this: If RUNQQ (or many others) were a subroutine instead of a function, my code would have a line like CALL RUNQQ(). Then whether I have implicit none or not, RUNQQ is not affected. When I build this program, wouldn't the compiler or linker produce a flag unless RUNQQ has not been provided for through a USE statement? And if USE has been provided, then the situated is not affected by IMPLICIT NONE--the declaration is provided by the USE module (and in fact if RUNQQ is explicitly declared I believe the compiler will flag an error due to multiple declarations).
More generally, say the routine in question is my own, say MYPROC (ARG), and say I have neglected to include the code for it in my project. If it is a function, my code will have something like IRETURN = MYPROC (ARG) and, if not explicitly declared as a function, the compiler will assume this is a reference to an array named MYPROC and complete the build (leading of course to runtime problems). But if it is a subroutine, my code will have CALL MYPROC (ARG), and during build time it will be flagged as an unresolved external, will it not?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you used MYPROC as a function, the compiler would assume it was a function unless declared as an array and if there was no MYPROC you'd get a linker error. Same for a subroutine. If you did have a MYPROC in your build but the return type or argument type/number did not match, generated interface checking would (usually) complain.
- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for putting up with this extended discussion.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I need to use RUNQQ command for linking a FORTRAN code with another one. But I have a problem. I have attached a simple example in which the problem occurs. When I run the "testrunqq2.f90" file the "discrete2.f90" is executed itself using RUNQQ command. It seems the command line " result=RUNQQ ('discrete2','-c -r')" does not run the other code at all. I see that the result is given equal to -1 which means the runqq failed! What shoud I do for that to run?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
See comments in the other thread where you asked this. When you run from Visual Studio, the default directory is the project directory, not where the EXE is.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Could you please tell me how I can change the default directory?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks so much for your reply. The problem I was concerned about is now solved by moving the EXE. file related to the second file from the "debug" folder to the folder where the first code was located.

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