Home > Archive > Fortran > April 2005 > Does F90 do type checking when calling module subroutines?
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 |
Does F90 do type checking when calling module subroutines?
|
|
| Neilen Marais 2005-04-25, 8:57 pm |
| Hi
I was under the impression that if you call subroutines from modules, f90
would check the call paramter types? I'm using Intel fortran under linux.
I have a subroutine defined in a module like this:
MODULE parseinput
..
..
..
INTERFACE read_namelists
MODULE PROCEDURE read_namelists
END INTERFACE
..
..
..
CONTAINS
SUBROUTINE read_namelists(infile)
IMPLICIT NONE
INTEGER(I4B), INTENT(in) :: infile
In another .f90 file, I included this subroutine with a USE parseinput
statement. Then I erroneously proceed to call it with a character array
(i.e. string) as parameter instead of an integer. Yet I get no compiler
error or warning! Is this the expected behaviour? If it is, is there
any way I can convince the compiler to let me know of my evil ways?
BTW, I4B is just an alias defined to mean 4 byte integer.
Thanks
Neilen
--
you know its kind of tragic
we live in the new world
but we've lost the magic
-- Battery 9 (www.battery9.co.za)
| |
| Richard E Maine 2005-04-25, 8:57 pm |
| In article <pan.2005.04.25.20.03.30.322672@chatsubo.lagged.za.net>,
Neilen Marais <junkmail@chatsubo.lagged.za.net> wrote:
> I was under the impression that if you call subroutines from modules, f90
> would check the call paramter types?
The standard doesn't quite require that, but it sure encourages it, and
I haven't yet seen a compiler that doesn't do it.
> I'm using Intel fortran under linux.
> I have a subroutine defined in a module like this:
>
> MODULE parseinput
> INTERFACE read_namelists
> MODULE PROCEDURE read_namelists
> END INTERFACE
> CONTAINS
>
> SUBROUTINE read_namelists(infile)
> IMPLICIT NONE
> INTEGER(I4B), INTENT(in) :: infile
>
>
> In another .f90 file, I included this subroutine with a USE parseinput
> statement. Then I erroneously proceed to call it with a character array
> (i.e. string) as parameter instead of an integer. Yet I get no compiler
> error or warning! Is this the expected behaviour? If it is, is there
> any way I can convince the compiler to let me know of my evil ways?
I would certainly gripe at a vendor that failed to diagnose such
problems, but first I'd wonder about one possibility for user confusion
here. In particular...
Is there some reason why you have the interface block? What that
interface block does is make a generic with this as one specific. It is
certainly possible that somewhere else there is another interface block
that also has a specific with a character dummy. I can't tell from
looking at this alone, but that is certainly the kind of reason why one
makes generics. If that's the case, then there is no error here except
for user confusion.
I might add that I find one thing slightly unusual about this generic -
namely that the generic and the specific (at least this specific) have
the same name. That might have contributed to the confusion. I had to
check the standard to see whether that was allowed for user-defined
generics. Apparently it is allowed... but I still wouldn't do it. I also
wonder whether that might be something unusual enough to have thrown off
the compiler.
I don't have a recent version of the Intel compiler handily installed to
check myself, but I might recommend making a severely cut down test case
(that is unless the above explanation leads you to the problem).
Shouldn't take much more than just the lines of code you showed, with a
procedure with no body (or maybe a body that just prints "here I am"),
plus a trivial main program to call it. That would be small enough to be
sure that there were no external factors (such as other interface
blocks) and would also allow experimentation with changing the name of
the specific to be different from that of the generic.
Or if you don't have reason to be using generics, you might just get rid
of the interface block - though I'd still be curious whether the
compiler is getting something wrong in it.
--
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
| |
| Ken Fairfield 2005-04-25, 8:57 pm |
| Neilen Marais wrote:
> Hi
>
> I was under the impression that if you call subroutines from modules, f90
> would check the call paramter types? I'm using Intel fortran under linux.
> I have a subroutine defined in a module like this:
>
> MODULE parseinput
> .
> .
> .
> INTERFACE read_namelists
> MODULE PROCEDURE read_namelists
> END INTERFACE
> .
> .
> .
> CONTAINS
>
> SUBROUTINE read_namelists(infile)
> IMPLICIT NONE
> INTEGER(I4B), INTENT(in) :: infile
>
>
> In another .f90 file, I included this subroutine with a USE parseinput
> statement. [...]
In addition to what Richard Maine said, I have some uneasiness
about the last sentence quoted above. If you know all this, pardon
my saying the obvious, but just to eliminate all sources of error...
F90 does not have a concept of "source file" as does C/C++.
It is important that the "USE parseinput" statement be present in
*every* subroutine or function, or the main program, that calls
read_namelists. Secondly, the USE statement does *not* include
the subroutine read_namelists. What it does is make any module
parameters or variables visible to the compiler, and the _interfaces_
for any module procedures defined in the module. That's a lot
different than, e.g., _including_ the source code for the subroutine.
-Ken
--
I don't speak for Intel, Intel doesn't speak for me...
Ken Fairfield
D1C Automation VMS System Support
who: kenneth dot h dot fairfield
where: intel dot com
| |
| Richard E Maine 2005-04-25, 8:57 pm |
| In article <d4jntd$grb$1@news01.intel.com>,
Ken Fairfield <my.full.name@intel.com> wrote:
> It is important that the "USE parseinput" statement be present in
> *every* subroutine or function, or the main program, that calls
> read_namelists.
Hmm. Good point. Very good point. Well, it doesn't have to be in every
subroutine, but it does have to be accessible (for example, it is fine
for the USE to be in a module - that will work for all the subroutines
in the module).
If the USE isn't in the subroutine (or its host), then the compiler ends
up assuming that read_namelists is an external procedure and it doesn't
get checked. That does tend to generate a linker error, but not a
compiler one.
Another fairly common error variant is to mistakenly have an EXTERNAL
statement for read_namelists; that will do a "nice" job of blocking the
host association.
At times I have wished for something similar to "implicit none" for
procedure interfaces - a statement that I think every procedure I'm
using should have an explicit interface, so XXXXX at me if one doesn't.
--
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
| |
| Neilen Marais 2005-04-26, 8:59 am |
| Hi
Yes, I am quite new to F90, and prone to misunderstanding ;) It does not
help that I inherited 45 kloc of hairball code written by people who
treated the whole project as a big matlab script, so I get from
time to time ;) In their defence, they also knew very little of F90 when
they started, and at least the quality of scientific work done with said
code has been much higher than the quality of the code itself ;)
On Mon, 25 Apr 2005 14:10:29 -0700, Richard E Maine wrote:
> Is there some reason why you have the interface block? What that
It's what the people before me did, so I assumed its served some purpose.
But, yes, now I can see that there is no need for it. I got rid of it. It
does not seem to be a factor.
> Or if you don't have reason to be using generics, you might just get rid
> of the interface block - though I'd still be curious whether the
> compiler is getting something wrong in it.
I can clearly remember getting wrong results because I passed a filename
to a function expecting a unit number, with no complaint from the
compiler, though I can't seem reproduce it at the moment.
On the other hand, I expected parameter checking to go hand in hand with
checking for the existence of an interface. Now I have learnt that f90 by
default makes an implicit function call if it can't find an interface. So
misspelled function / subroutine calls only get caught at link time. Is
this correct?
Thanks
Neilen
--
you know its kind of tragic
we live in the new world
but we've lost the magic
-- Battery 9 (www.battery9.co.za)
| |
| Steve Lionel 2005-04-26, 4:00 pm |
| On Mon, 25 Apr 2005 22:03:31 +0200, Neilen Marais
<junkmail@chatsubo.lagged.za.net> wrote:
>In another .f90 file, I included this subroutine with a USE parseinput
>statement. Then I erroneously proceed to call it with a character array
>(i.e. string) as parameter instead of an integer. Yet I get no compiler
>error or warning! Is this the expected behaviour? If it is, is there
>any way I can convince the compiler to let me know of my evil ways?
I would very much like to see a complete example that demonstrates this. I
have never encountered a case where Intel Fortran failed to complain about
this sort of mismatch. Please submit your test case to Intel Premier Support
(see link below.)
My guess is that your paraphrasing of the code does not represent what the
code actually says.
Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH
User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://developer.intel.com/software/products/support/
| |
| Richard E Maine 2005-04-26, 4:00 pm |
| In article <pan.2005.04.26.08.34.06.212774@chatsubo.lagged.za.net>,
Neilen Marais <junkmail@chatsubo.lagged.za.net> wrote:
> Now I have learnt that f90 by
> default makes an implicit function call if it can't find an interface. So
> misspelled function / subroutine calls only get caught at link time. Is
> this correct?
Yes, that is correct. That's what I was referring to when I said I
wished there were an equivalent to "implicit none" for interfaces.
You do tend to get an error from this at link time, though, so not all
is lost. It is just that compile time would be better and clearer. The
"link name" of a module procedure is different from that of an external
procedure - it has to be so because it is legal to have an external
procedure and a module procedure of the same name (and, in fact,
multiple module procedures of the same name in different modules). I
wouldn't advise having such an external procedure, but it is allowed, so
the compiler has to have a way to distinguish it.
Generally, you will see a "link name" of an external procedure will have
something like an underscore added to the end (details and fine points
vary), while the "link name" of a module procedure will have both the
module name and the procedure name conflated somehow.
--
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
|
|
|
|
|