Home > Archive > Fortran > May 2004 > function prototypes
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
function prototypes
|
|
| Lynn McGuire 2004-05-12, 9:09 pm |
| Does Fortran 95 have function prototypes like C and C++ ? If so,
do any of the Win32 compilers support this ?
We find that one of the worst problems that we have in our 400,000
lines of F77 code with 3,500 subroutines, is argument mismatch. We
currently use the Open Watcom F77 and C compilers for Win32
(been using Watcom since 1992 with no major reason to change yet).
Thanks,
Lynn McGuire
| |
| Michael Metcalf 2004-05-12, 9:09 pm |
|
"Lynn McGuire" <nospam.mmcguire@nospam.mylinuxisp.com> wrote in message
news:409dbbac$0$17097$811e409b@news.mylinuxisp.com...
> Does Fortran 95 have function prototypes like C and C++ ? If so,
> do any of the Win32 compilers support this ?
>
> We find that one of the worst problems that we have in our 400,000
> lines of F77 code with 3,500 subroutines, is argument mismatch. We
> currently use the Open Watcom F77 and C compilers for Win32
> (been using Watcom since 1992 with no major reason to change yet).
>
No, but many f95 compilers check interfaces as an option, even with implicit
interfaces. There are methods to get explicit interfaces for old code, for
instance by packaging it into modules (which, however, requires the end
statements to be modified), or by generating interface blocks with a tool
such as convert.f90.
Hope that helps,
Mike Metcalf
| |
| beliavsky@aol.com 2004-05-12, 9:09 pm |
|
"Michael Metcalf" <michael.metcalf@t-online.de> wrote:[color=darkred]
>
>"Lynn McGuire" <nospam.mmcguire@nospam.mylinuxisp.com> wrote in message
>news:409dbbac$0$17097$811e409b@news.mylinuxisp.com...
When I programmed in F77 I found FTNCHEK to be helpful in finding mismatched
arguments and other problems -- see http://www.dsm.fordham.edu/~ftnchek/
| |
| Lynn McGuire 2004-05-12, 9:09 pm |
| > The Lahey/Fujitsu Fortran 95 compiler can detect mismatched arguments in
> F77 code when all the sources are compiled together, using the -chkglobal
> option. The Express version, which is just a command-line compiler, costs
> $250. You can also check your code for free using Lahey Fortran at http://www.lahey.com/check.htm
I just remembered that Open Watcom F77 does that also automatically
when all the sources are compiled together. Since our source is in 3500
files, I will try merging them into one file and see what happens. Might
be very interesting (and slower than anything to compile !).
Thanks,
Lynn
| |
| Herman D. Knoble 2004-05-12, 9:09 pm |
| Lynn:
You could try using Salford Personal Fortran 77 (free for non-commercial purposes):
http://www.salfordsoftware.co.uk/co.../downloads.html
This compiler detects argument/parameter mismatches, uninitialized variables,
and subscript/string ranges (and more) - at run time.
Skip Knoble
On Sun, 9 May 2004 00:10:11 -0500, "Lynn McGuire" <nospam.mmcguire@nospam.mylinuxisp.com>
wrote:
-|Does Fortran 95 have function prototypes like C and C++ ? If so,
-|do any of the Win32 compilers support this ?
-|
-|We find that one of the worst problems that we have in our 400,000
-|lines of F77 code with 3,500 subroutines, is argument mismatch. We
-|currently use the Open Watcom F77 and C compilers for Win32
-|(been using Watcom since 1992 with no major reason to change yet).
-|
-|Thanks,
-|Lynn McGuire
-|
Herman D. (Skip) Knoble, Research Associate
(a computing professional for 38 years)
Email: SkipKnobleLESS at SPAMpsu dot edu
Web: http://www.personal.psu.edu/hdk
Penn State Information Technology Services
Academic Services and Emerging Technologies
Graduate Education and Research Services
Penn State University
214C Computer Building
University Park, PA 16802-21013
Phone:+1 814 865-0818 Fax:+1 814 863-7049
| |
| Richard Maine 2004-05-12, 9:09 pm |
| "Lynn McGuire" <nospam.mmcguire@nospam.mylinuxisp.com> writes:
> Does Fortran 95 have function prototypes like C and C++ ?
No. It doesn't have ones "like" C and C++.
But it has something much better...
> do any of the Win32 compilers support this ?
Yes. All the f90/f95 ones do. I almost said that it is in the
f90 standard, but then remembered that the standard doesn't actually
mandate the helpful checks, as a few other posters here would
probably have reminded me. But the standard certainly encourages
it. I've never seen an f90 compiler that doesn't.
> We find that one of the worst problems that we have in our 400,000
> lines of F77 code with 3,500 subroutines, is argument mismatch.
Yep. That used to be a big problem in f77. Been there. It has never
been a significant issue in any new f90 code I've worked with. (The
old, inherited f77 code compiled with new compiles doesn't count as
"new f90 code").
Write all procedures as module procedures instead of external ones.
Then you get the checking of function proptotypes without actually
having to writ ethe prototypes. In essence, the compiler writes them
for you. Besides saving effort, this has the *HUGE* advantage that
the prototype and the procedure will actually agree. With manually
written propotypes, you get checking that the call matches the
prototype, but you don't necessarily know that the prototype matches
the procedure. (There may be a way to check that in C; my C
proficiency isn't good enough to know, but that's a side issue here.)
If for some reason you choose not to use module procedures, you
can write interface bodies (preferably in a module). These are
a PITA to write, and you do have to manually check them against
the procedure, but at least you only have one interface body per
procedure to check (instead of many calls). You also have the
maintenance issue of making sure that the interface body and the
procedure stay in sync. This is as close as you can come to
something like C header files; I consider it a royal pain (just like
I'd consider writing C header files to be a pain).
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| Walter Spector 2004-05-12, 9:09 pm |
| Lynn McGuire wrote:
> ... Since our source is in 3500
> files, I will try merging them into one file and see what happens. Might
> be very interesting (and slower than anything to compile !).
It is very quick to create a little Fortran module, lets call it all.f,
which contains 'include' statements for each of your 3500 files. Simply
create a list of files with 'ls -1 *.f > all.f'. Then use vi or the
text editor of your choice to turn this into a bunch of 'include'
statements:
me$ ls *.f > all.f
me$ vi *.f
1,$s?^? include "?
1,$s?$?"?
:wq
me$
Then compile all.f.
Since the program units are not in a proper Fortran-90 module, there is
no guarantee that a complete global check will be performed. There are
compilers that will only issue errors in a forward direction. That is,
the errors are flagged only when a call to a previously compiled program
unit has been encountered. So after fixing any problems encountered in
the above, you should then sort all.f in the opposite direction to find
more problems.
As others have noted, strong interface checking is a part of Fortran-90 -
provided you place all your procedures in modules (or write interface
blocks for them). So if you really want to get radical, change the all.f
you created above to the following:
module all
contains
:
: all the include statements here
:
end module
This will require that each of your 3500 files should have the last line
of their program units say "end subroutine" (or "end function") instead
of simply "end". (I've found that doing this is also usually easy to
automate with modern text processing tools.)
Interface blocks are kinda the Fortran-90 equivalent to C's function
prototypes. Ignoring their use in generic/operator overloading for the
moment, I tend to use them only where I do not have the source code for
the callee, or if the callee is written in some non-Fortran language.
Walt
-...-
Walt Spector
(w6ws at earthlink dot net)
| |
| Michael Metcalf 2004-05-12, 9:09 pm |
|
"Richard Maine" <nospam@see.signature> wrote in message
news:m1vfj4s3h9.fsf@macfortran.local...
> Write all procedures as module procedures instead of external ones.
> Then you get the checking of function proptotypes without actually
> having to writ ethe prototypes. In essence, the compiler writes them
> for you. Besides saving effort, this has the *HUGE* advantage that
> the prototype and the procedure will actually agree.
>
Yes, but if just dumping f77 code into a new module, the user MUST remember
to add, as a minimum, either function or subroutine, as appropriate, to each
subprogram end statement. A bind.
> If for some reason you choose not to use module procedures, you
> can write interface bodies (preferably in a module). These are
> a PITA to write,
but, for F77 code, covert.f90 has an option to generate them code for you.
Regards,
Mike Metcalf
| |
| John Collins 2004-05-12, 9:09 pm |
| WinFPT (http://simcon.uk.com) and PlusFORT (http://polyhedron.co.uk)
will both pick up mis-matched arguments, and many other exciting
features.
Best wishes,
John
john_collins@simcon.uk.com
| |
|
| Michael Metcalf (aka Bruce) was almost, but not quite, entirely unlike tea:
>
> "Richard Maine" <nospam@see.signature> wrote in message
> news:m1vfj4s3h9.fsf@macfortran.local...
Every now and then, I come across a subtle bug in my old f77 code,
that I just cannot work out. This is my cue to convert the routines
involved into F90.
I run a couple of emacs macros over the code (I think I tried
convert.f90 at one stage, and ran into some sort of problem - possibly
the fact that the code never was pure F77 - it used F90 comments
sometimes, and a few other oddities) to get free-format code, then I
wrap the module nicities around it.
But only yesterday, it came to link stage after fixing all the calls
to old routines in redundant code, and there were millions of
unresolved functions at link time. Arrrrh! After much hair pulling, I
realised I forgot all the "Use convertlbxy".
Found a couple of potential bugs, but not the ones that are crashing
my code, alas.
[color=darkred]
> Yes, but if just dumping f77 code into a new module, the user MUST remember
> to add, as a minimum, either function or subroutine, as appropriate, to each
> subprogram end statement. A bind.
If I am understanding you correct, you mean the last line in:
FUNCTION rsqr(val)
IMPLICIT NONE
REAL, INTENT(IN) :: val
REAL rsqr
rsqr=val*val
RETURN
END FUNCTION rsqr
Luckily for me, the act of pressing 'tab' in emacs automatically does
the pretty printing and the format of the last line, and a few other
things. And repeatedly pressing tab is part of my macro :)
--
TimC -- http://astronomy.swin.edu.au/staff/tconnors/
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
| |
| James Van Buskirk 2004-05-12, 9:09 pm |
| "TimC" <tconnors@no.astro.spam.swin.accepted.edu.here.au> wrote in message
news:slrn-0.9.7.4-27313-15652-200405111100-tc@hexane.ssi.swin.edu.au...
> Luckily for me, the act of pressing 'tab' in emacs automatically does
> the pretty printing and the format of the last line, and a few other
> things. And repeatedly pressing tab is part of my macro :)
But emacs likely has problems figuring out which EXTERNAL
statements correspond to module procedures and which variable
declarations are for the names of external procedures which
will become module procedures and taking appropriate action...
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
| |
|
| James Van Buskirk (aka Bruce) was almost, but not quite, entirely unlike tea:
> "TimC" <tconnors@no.astro.spam.swin.accepted.edu.here.au> wrote in message
> news:slrn-0.9.7.4-27313-15652-200405111100-tc@hexane.ssi.swin.edu.au...
>
>
> But emacs likely has problems figuring out which EXTERNAL
> statements correspond to module procedures and which variable
> declarations are for the names of external procedures which
> will become module procedures and taking appropriate action...
There is some human element involved in translating to modules,
unfortunately.
And I can see this would probably become a *big* job when you have
3500 source files.
--
TimC -- http://astronomy.swin.edu.au/staff/tconnors/
"32-bit patch for a 16-bit GUI shell running on top of an
8-bit operating system written for a 4-bit processor by a
2-bit company who cannot stand 1 bit of competition."
| |
| Helge Avlesen 2004-05-12, 9:09 pm |
| TimC <tconnors@no.astro.spam.swin.accepted.edu.here.au> writes:
| Luckily for me, the act of pressing 'tab' in emacs automatically does
| the pretty printing and the format of the last line, and a few other
| things. And repeatedly pressing tab is part of my macro :)
also hope you are familiar with ESC C-q (runs f90-indent-subprogram)
--
Helge
| |
| Michael Metcalf 2004-05-12, 9:09 pm |
|
"TimC" <tconnors@no.astro.spam.swin.accepted.edu.here.au> wrote in message
news:slrn-0.9.7.4-27313-15652-200405111100-tc@hexane.ssi.swin.edu.au...
> (I think I tried
> convert.f90 at one stage, and ran into some sort of problem - possibly
> the fact that the code never was pure F77 - it used F90 comments
> sometimes, and a few other oddities)
>
For the record, convert.f90 does handle f90 style comments and a lot of
common extensions.
>
> If I am understanding you correct, you mean the last line in:
[snip]
> END FUNCTION rsqr
>
Yes. As a minimum, the function keyword must appear, in this case.
convert.f90 adds both the keyword and the name automatically.
Regards,
Mike Metcalf
| |
| Lynn McGuire 2004-05-12, 9:09 pm |
| > There is some human element involved in translating to modules,
> unfortunately.
>
> And I can see this would probably become a *big* job when you have
> 3500 source files.
This should be easily doable with a script. I converted all of our
F77 code from single precision to double precision several years
ago using a script. Sounds easy, was very difficult since we have
been using dynamic memory in our software for over 25 years.
We have integer arrays equivalenced to real arrays everywhere
in our code which required a change in just about every other line
of code since none of the major compilers supported integer*8
at the time.
> "32-bit patch for a 16-bit GUI shell running on top of an
> 8-bit operating system written for a 4-bit processor by a
> 2-bit company who cannot stand 1 bit of competition."
Hey, I like that ! I have actually added 32 bit patches to our old
Win16 GUI in the not so distant past. Moving to Win32 was a
big sigh of relief !
Lynn
| |
|
| Lynn McGuire (aka Bruce) was almost, but not quite, entirely unlike tea:
>
> Hey, I like that ! I have actually added 32 bit patches to our old
> Win16 GUI in the not so distant past. Moving to Win32 was a
> big sigh of relief !
Unfortunately, not all of my sigs are attributed - I certainly can't
remember where I got that from, and seems to be in wide use.
--
TimC -- http://astronomy.swin.edu.au/staff/tconnors/
Love makes the world go 'round, with a little help from intrinsic
angular momentum.
| |
| Dave Thompson 2004-05-19, 1:31 am |
| On 10 May 2004 08:31:46 -0700, Richard Maine <nospam@see.signature>
wrote:
> "Lynn McGuire" <nospam.mmcguire@nospam.mylinuxisp.com> writes:
>
<snip>[color=darkred]
> Write all procedures as module procedures instead of external ones.
> Then you get the checking of function proptotypes without actually
> having to writ ethe prototypes. In essence, the compiler writes them
> for you. Besides saving effort, this has the *HUGE* advantage that
> the prototype and the procedure will actually agree. With manually
> written propotypes, you get checking that the call matches the
> prototype, but you don't necessarily know that the prototype matches
> the procedure. (There may be a way to check that in C; my C
> proficiency isn't good enough to know, but that's a side issue here.)
>
It's a side issue, but for comparison or interest:
In C if you truly write a prototype declaration -- i.e. the new-in-C89
syntax, not K&R1 syntax, which can still be used for 'external'
declarations which people sometimes misuse 'prototype' to mean -- in a
header file that you #include in the caller(s), _and_ you #include the
same header file in (the file containing) the implementation (which C
calls definition) which is also in prototype/new syntax, the compiler
is required to check matching and diagnose any mismatch. (gcc, as a
nonstandard option, will also check a prototype declaration against a
_K&R1_ definition; this used to be a fairly common practice to ease
backporting to prestandard compilers, as the header declarations can
be K&R1-ized by a simple macro, but the definitions cannot.)
In C++ the K&R1 syntax is gone; you must use prototype syntax, and if
a declaration is present before the definition it must be checked. And
for a (noninline) class member function aka method, but not a free
function, there must be a prior definition of the class, which
includes declarations of all methods (and data members); and while the
language doesn't require or check it, that class definition usually is
#include'd from the same file the callers use.
However: in software environments/organizations (significantly) more
complicated than a single directory of a few files, there is still a
risk that both caller and caller write the same #include "foo.h" but
are compiled in ways that get different (and nonidentical) files
included; or that both caller(s) and callee are compiled with the same
header(s) but the resulting object is not managed correctly and
mismatched objects are linked and run; plus always the problem that
you forget to recompile a caller affected by a change and don't
have/use something like make or an IDE to handle this automatically.
These problems can also apply to Fortran modules as actually
implemented TTBOMK; although both C and Fortran standards would
*allow* an implementation to (re)check at link time in practice IME
they use (crosslanguage) linkers that don't. The only language I know
compiled in the traditional sense (unlike say Java) that always checks
consistency is Ada, and its implementations can't do so with "normal"
linkers. I've heard Eiffel also does, but haven't looked.
In C there is the further risk that the declarations in the header
file depend on preprocessor macros that are not #define'd
consistently. Fortran does not have *this* problem: PARAMETERs are
confined to scopes; and can't be complete types although they can
(very usefully) be KINDs. In C++ some (many?) of the things you need
macros for in C can be done better, e.g. with templates, though you
aren't prevented from using the dangerous old C ways.
> If for some reason you choose not to use module procedures, you
> can write interface bodies (preferably in a module). These are
> a PITA to write, and you do have to manually check them against
> the procedure, but at least you only have one interface body per
> procedure to check (instead of many calls). You also have the
> maintenance issue of making sure that the interface body and the
> procedure stay in sync. This is as close as you can come to
> something like C header files; I consider it a royal pain (just like
> I'd consider writing C header files to be a pain).
In the Fortran -- and Java -- approach you have a complementary but
(IME) rarer problem: you can't compile a calling (higher-level?) unit
until you the called (lower-level) units are compilable and compiled.
If you are simply writing top-down, this only requires you to write
and compile stubs earlier than you might want, which is a small waste
of time and distraction; but if you are making changes to an existing
(large) program significant enough to temporarily invalidate (lots of)
good code, you must remove it or comment it out of the lower units to
get a good compile and then make sure you put back the right versions
in the right places later; especially for experimental or temporary
changes, this induces an unnecessary risk of damaging parts of the
program that in C you can just leave untouched.
And in addition you must play tricks to handle mutual (recursive)
dependencies, or (arguably) warp the design to avoid them.
- David.Thompson1 at worldnet.att.net
|
|
|
|
|