From: Bill on 4 Jan 2010 13:54 Is the following program Fortran 95 conforming? module mod1 contains subroutine sub(x) real x end subroutine sub end module mod1 module mod2 use mod1 interface sub module procedure sub, sub_int end interface sub contains subroutine sub_int(i) integer i end subroutine sub_int end module mod2 program prog use mod1 use mod2 call sub(1) end program prog mod1 is an existing module that cannot be changed. mod2 is attempting to extend the name sub from mod1 to accept an integer argument. I have 4 compilers that reject this program, and 5 that accept it. Some that reject it will accept it with seemingly minor changes (e.g. reverse the order of the USE statements in prog, omit USE mod1 in prog, ...). Error messages from the objecting compilers are: 1) Illegal attempt to redefine symbol sub 2) Symbol SUB found both in module MOD1 and in MOD2 detected at CALL(a)SUB 3) "SUB" has been use associated from module "MOD1" and at least one more module. It must not be referenced. 4) call sub(1) 1 Error: Type mismatch in argument 'x' at (1); passed INTEGER(4) to REAL (4) It seems to me that the following constraint on the definition of an interface block: Constraint: The MODULE PROCEDURE specification is allowed only if the interface-block has a generic-spec and has a host that is a module or accesses a module by use association; each procedure-name must be the name of a module procedure that is accessible in the host indicates that sub can be used in the generic interface since it is a module procedure and is accessible in mod2. But maybe there is something somewhere else in the standard that I'm missing. Thanks, Bill
From: Paul van Delst on 4 Jan 2010 14:52 What if you make the changes I made below: Bill wrote: > Is the following program Fortran 95 conforming? > > module mod1 > contains > subroutine sub(x) > real x > end subroutine sub > end module mod1 > > module mod2 use mod1, sub_real=>sub private public :: sub > interface sub module procedure sub_real, sub_int > end interface sub > contains > subroutine sub_int(i) > integer i > end subroutine sub_int > end module mod2 > > program prog ! use mod1 ! no longer needed here > use mod2 > call sub(1) > end program prog ? I can't recall if there is a constraint in the standard that says you can't name a procedure and an interface the same (I assume there is one), but, regardless, I find it confusing even if it was allowed. By using the rename capability, use mod1, sub_real=>sub in mod2 you bypass any conformance issues, and general confused-user issues too. :o) And you only have to USE one module, mod2, in the main program. cheers, paulv
From: Richard Maine on 4 Jan 2010 22:32 Paul van Delst <paul.vandelst(a)noaa.gov> wrote: > I can't recall if there is a constraint in the standard that says you > can't name a procedure and an interface the same (I assume there is one), No, there isn't. Quite the opposite, there is language specifically allowing it.... except that you have the terminology wrong above. Yes, I know that you declare a generic procedure using a construct that starts with the keyword INTERFACE. I wouldn't have done the syntax that way, but it is about 2 decades too late for that. In spite of that syntax, what you are declaring is not an interface. You are declaring a generic procedure. Declaring an interface is something completely different. It is, in my view, unfortunate and confusing that you might in some cases end up declaring both ageneric procedure and also some interfaces in the same "interface block", which starts with the keyword "interface". I particularly mention this because there are completely diferent issues with declaring an interface for a procedure. No, you can't declare an interface for a module procedure because it already has one. But you can put the module procedure name in an interface block to give it a generic name, and yes, that generic name can be the same as the module procedure name. > but, regardless, I find it > confusing even if it was allowed. I agree with that part. I think there is evidence that some compilers also get confused. It counts as a compiler bug, but such things have been known to exist. By having the module procedure and the generic block in different modules, you have given the compilers extra ways to get it wrong. Sounds like several of them do get it wrong. That doesn't horribly surprise me, as it is a tricky bit, and one which probably doesn't come up a lot. "Normally", you can't USE the same name from two different modules. This is an exception, and a tricky enough one that I can easily see compilers missing it. (One of the two that I tried missed it). Anyway, to directly answer the question, yes, the code appears to be standard conforming as far as I can see. As to workarounds, well, I assume you can figure those out (and Paul mentioned one), but that's not the question I heard being asked. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain
From: Bill on 5 Jan 2010 09:46 Thank you to both Paul, for his suggestion of renaming sub to sub_real in mod2, and Richard, for his ever trustworthy judgement on standard conformance. That's what I wanted to hear before I file a bug report with the 4 vendors whose compilers failed. As to Paul's comment that USE mod1 is no longer needed in prog, it never was needed to get sub -- that comes from the generic interface in mod2. The USE mod1 statement is there because prog uses other things from mod1 (well, not in this bug report program, but in the real program). But instead of omitting it, I can replace it with USE mod1, nada=>sub. This seems to remove the confusion about sub coming from two modules, and for 3 of the 4 failing compilers, that is all that is needed. The 4th one still complains about sub being redefined in mod2, unless I also add Paul's suggestion of renaming sub to sub_real on the USE mod1 statement in mod2 (which also includes changing sub to sub_real in the MODULE PROCEDURE statement, of course). With just those changes the program works with all 7 compilers that I have available, so I guess that's my best workaround. As for it being confusing to use a generic name that is the same as a module procedure name, with that procedure in a different module, I was thinking of it as being essentially the same as extending the generic interface of intrinsic procedures to have an argument of a user defined type. I have an existing procedure in mod1 which I want to extend to accept a different kind of argument by defining a generic interface. The only difference is that you wouldn't list the intrinsic procedure on the MODULE PROCEDURE statement, and the procedure in mod1 doesn't already have a generic interface like an intrinsic procedure. Bill
|
Pages: 1 Prev: forall Vs Do...enddo Vs Where Next: Decline in posting counts |