Code Comments
Programming Forum and web based access to our favorite programming groups.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)
Post Follow-up to this messageIn 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
Post Follow-up to this messageNeilen 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
Post Follow-up to this messageIn 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
Post Follow-up to this messageHi 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 getfrom 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)
Post Follow-up to this messageOn 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 Suppor t (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/
Post Follow-up to this messageIn 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
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.