|
|||
|
I want to do something I've never done before: write a subroutine which
has an optional parameter which is the name of a function. Presumably this is just a combination of a dummy procedure and the OPTIONAL attribute. Consider a collection of library routines (i.e. compiled then linked to user-written code) which has an optional dummy procedure as the argument to one of its routines. Is this a case where, if one wants an explicit interface, one must write it by hand, as opposed to having it available via a USEd module? The library routines are compiled and linked then the user writes his own code to call them and also a procedure whose name is passed as an argument to one of the library routines. Thus, the procedure doesn't even exist when the library routines are compiled. I like explicit interfaces and I don't like duplicating code by hand, which is why I like an explicit interface through a module procedure. However, in this case (which has nothing to do with whether it is OPTIONAL or not), there seems to be no alternative. Does anyone have a SHORT working example? |
|
|
||||
|
||||
|
|
|
|||
|
In article <jlsj7m$act$1@online.de>,
helbig@astro.multiCLOTHESvax.de (Phillip Helbig---undress to reply) wrote: > I want to do something I've never done before: write a subroutine which > has an optional parameter which is the name of a function. Presumably > this is just a combination of a dummy procedure and the OPTIONAL > attribute. I don't have an example with an OPTIONAL dummy procedure, but I do this all the time with regular dummy procedure arguments. Yes, this is a situation where you must write an interface block. It is too bad that the language requires this error-prone redundancy, but it does. Compilers lately are getting pretty good with checking actual and dummy argument interfaces, so they catch some of the mismatches that sometimes occur, but I do not think this is required to be detected by the language standard, so you are at the mercy of your compiler. If you have access to several compilers during code development, this is one of the situations where it is good to run your code past all of them. $.02 -Ron Shepard |
|
|||
|
In article <ron-shepard-963A47.14221108042012@news60.forteinc.com>, Ron
Shepard <ron-shepard@NOSPAM.comcast.net> writes: > > I want to do something I've never done before: write a subroutine which > > has an optional parameter which is the name of a function. Presumably > > this is just a combination of a dummy procedure and the OPTIONAL > > attribute. > > I don't have an example with an OPTIONAL dummy procedure, but I do > this all the time with regular dummy procedure arguments. Yes; I'm familiar with those. Presumably I just need to have an OPTIONAL statement (without declaring anything else). > Yes, this > is a situation where you must write an interface block. OK. > It is too > bad that the language requires this error-prone redundancy, but it > does. Compilers lately are getting pretty good with checking actual > and dummy argument interfaces, so they catch some of the mismatches > that sometimes occur, but I do not think this is required to be > detected by the language standard, so you are at the mercy of your > compiler. Do you mean at run-time? |
|
|||
|
Ron Shepard <ron-shepard@NOSPAM.comcast.net> wrote:
> In article <jlsj7m$act$1@online.de>, > helbig@astro.multiCLOTHESvax.de (Phillip Helbig---undress to > reply) wrote: > > > I want to do something I've never done before: write a subroutine which > > has an optional parameter which is the name of a function. Presumably > > this is just a combination of a dummy procedure and the OPTIONAL > > attribute. > > I don't have an example with an OPTIONAL dummy procedure, but I do > this all the time with regular dummy procedure arguments. Yes, this > is a situation where you must write an interface block. It is too > bad that the language requires this error-prone redundancy, but it > does. Yes. This has nothing in particular to do with OPTIONAL. This is one of the few places where I write interface bodies. Interfaces for C functions are another. F2003 does provide two new alternatives here using the PROCEDURE statement. One of them also involves writing an explicit interface, but I still think it slightly better. In particular, you can write an abstract interface, which you then use in a PROCEDURE statement. While this does still involve writing an interface body, that interface body isn't directly tied to the particular dummy argument. Having declared the abstract interface once, you can use it multiple times, perhaps for multiple procedures with dummy arguments or for procedure pointers. I find it simillar to a derived type, which you declare once and then use for multiple objects. The other new way in f2003 avoids needing to write an interface body at all. You can use the PROCEDURE statement with the name of some other procedure that has the interface you need. For example, you could do subroutine sub(proc) use some_module_with_a_suitable_procedure_proc1 procedure(proc1) :: proc .... I think that's the right syntax, but I didn't drag out the standard to check. Basically, it says that proc has the same interface as proc1. Odds are that you have a suitable proc1 around somewhere; after all, you need to have at least one procedure somwhere with that interface in order to be able to call sub. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain |
|
|||
|
In article <1ki8jj1.i1cyrtlpq46N%nospam@see.signature>,
nospam@see.signature (Richard Maine) writes: > > > I want to do something I've never done before: write a subroutine which > > > has an optional parameter which is the name of a function. Presumably > > > this is just a combination of a dummy procedure and the OPTIONAL > > > attribute. > > > > I don't have an example with an OPTIONAL dummy procedure, but I do > > this all the time with regular dummy procedure arguments. Yes, this > > is a situation where you must write an interface block. It is too > > bad that the language requires this error-prone redundancy, but it > > does. > > Yes. This has nothing in particular to do with OPTIONAL. This is one of > the few places where I write interface bodies. Right; apparently necessary in F95. > F2003 does provide two new alternatives here using the PROCEDURE > statement. Interesting. > One of them also involves writing an explicit interface, but I still > think it slightly better. A bit better. > The other new way in f2003 avoids needing to write an interface body at > all. You can use the PROCEDURE statement with the name of some other > procedure that has the interface you need. For example, you could do > > subroutine sub(proc) > use some_module_with_a_suitable_procedure_proc1 > procedure(proc1) :: proc > .... > > I think that's the right syntax, but I didn't drag out the standard to > check. Basically, it says that proc has the same interface as proc1. > Odds are that you have a suitable proc1 around somewhere; after all, you > need to have at least one procedure somwhere with that interface in > order to be able to call sub. That is really what I need. Unfortunately, VMS (and the F95 compiler on ALPHA) is so good that I am stuck with F95. I think this is the first time I actually need something which a later standard provides. An alternative might be to hard-code an interface into the module containing the library routines and force the user to give his procedure that name. Of course, this means that there is no longer the possibility to pass different procedures as arguments, but a workaround would be have an additional integer argument to the library routine. The one-size-fits-all user-written procedure would then be called from within the library routine with this additional argument which would be used in a CASE construct to select, internally, which code (i.e. corresponding to what should be separate procedures) should be used. |
|
|||
|
Phillip Helbig---undress to reply wrote:
> > I want to do something I've never done before: write a subroutine which > has an optional parameter which is the name of a function. Presumably > this is just a combination of a dummy procedure and the OPTIONAL > attribute. <Snip> > Does anyone have a SHORT working example? Phillip, is something like the "code" which follows that you are after? I'm after a similar thing, but it does not compile, since a data object and not a function name is expected by the compilers (exception is the Lahey compiler which produces executable code). I'm not sure what the standard says on this. Maybe a pointer to function would be the solution (passing the pointer as optional argument ?) /Sakis PROGRAM tets IMPLICIT NONE !REAL, EXTERNAL :: quad INTERFACE REAL FUNCTION quad(x) REAL, INTENT(IN) :: x END FUNCTION quad END INTERFACE INTERFACE SUBROUTINE subr( r, f ) REAL, INTENT(IN) :: r OPTIONAL :: f END SUBROUTINE subr END INTERFACE CALL subr( 10.2 ) CALL subr( 10.2, quad ) END PROGRAM tets SUBROUTINE subr( r, f ) IMPLICIT NONE REAL, INTENT(IN) :: r OPTIONAL :: f !REAL, EXTERNAL, OPTIONAL :: f INTERFACE REAL FUNCTION f(x) REAL, INTENT(IN) :: x END FUNCTION f END INTERFACE IF ( PRESENT(f) ) THEN PRINT *, r + f(r) ELSE PRINT *, r ENDIF END SUBROUTINE subr REAL FUNCTION quad(x) IMPLICIT NONE REAL, INTENT(IN) :: x quad = x**2 END FUNCTION quad -- ------- e-mail: replace <nada> by <com> A.M. |
|
|||
|
Athanasios Migdalas wrote:
> > Phillip Helbig---undress to reply wrote: > >> >> I want to do something I've never done before: write a subroutine which >> has an optional parameter which is the name of a function. Presumably >> this is just a combination of a dummy procedure and the OPTIONAL >> attribute. > <Snip> >> Does anyone have a SHORT working example? > > Phillip, > > is something like the "code" which follows that you are after? I'm after a > similar thing, but it does not compile, since a data object and not a > function name is expected by the compilers (exception is the Lahey > compiler which produces executable code). I'm not sure what the standard > says on this. Maybe a pointer to function would be the solution (passing > the pointer as optional argument ?) > > /Sakis > > PROGRAM tets > IMPLICIT NONE > !REAL, EXTERNAL :: quad > > INTERFACE > REAL FUNCTION quad(x) > REAL, INTENT(IN) :: x > END FUNCTION quad > END INTERFACE > > INTERFACE > SUBROUTINE subr( r, f ) > REAL, INTENT(IN) :: r > OPTIONAL :: f > END SUBROUTINE subr > END INTERFACE > > CALL subr( 10.2 ) > CALL subr( 10.2, quad ) > > END PROGRAM tets > > SUBROUTINE subr( r, f ) > IMPLICIT NONE > REAL, INTENT(IN) :: r > OPTIONAL :: f > !REAL, EXTERNAL, OPTIONAL :: f > > INTERFACE > REAL FUNCTION f(x) > REAL, INTENT(IN) :: x > END FUNCTION f > END INTERFACE > > IF ( PRESENT(f) ) THEN > PRINT *, r + f(r) > ELSE > PRINT *, r > ENDIF > > END SUBROUTINE subr > > > REAL FUNCTION quad(x) > IMPLICIT NONE > REAL, INTENT(IN) :: x > quad = x**2 > END FUNCTION quad > > > > I did it again ... change the interface in the program to INTERFACE SUBROUTINE subr( r, f ) REAL, INTENT(IN) :: r REAL, EXTERNAL,OPTIONAL :: f END SUBROUTINE subr END INTERFACE and it compiles and runs with *any* compiler. /Sakis -- ------- e-mail: replace <nada> by <com> A.M. |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|