program...
call first(...)
end
subroutine first(a,b,c)
integer a
integer, optional :: b,c
c-- how do I call second??
c-- like this??
if ( present(b) .and. present(c)) then
call second(a,b=b,c=c)
elseif(.not. present(b) .and. present(c)) then
call second(a,c=c)
elseif( present(b) .and. .not. present(c)) then
call second(a,b=b)
else
call second(a)
endif
c-- this seems very messy particularly if there are more than 2
c-- optional arguments, any more generic method?
return
end
subroutine second(a,b,c)
integer a
integer, optional :: b,c
...
return
end
Jan
You can do exactly what you want, however, you MUST have an explicit
interface. I have modified your code to acheive this using internal
proceures; using a module containing those procedure would be equally valid
("Fortran 90/95 Explained", Section 5.13).
Regards,
Mike Metcalf
program optional
call first(5)
call first(6, c=4)
contains
subroutine first(a,b,c)
integer a
integer, optional :: b,c
call second(a,b=b,c=c)
call second(a,c=c)
call second(a,b=b)
call second(a)
return
end subroutine
subroutine second(a,b,c)
integer a
integer, optional :: b,c
print *, a, present(b), present(c)
return
end subroutine
end program
> "Adrian" <ac...@hotmail.com> wrote in message
> news:6f89be88.03110...@posting.google.com...
>> I have a need to pass the presence or otherwise of optional aguments
>> down the call tree, eg:
>
> You can do exactly what you want, however, you MUST have an explicit
> interface.
And note that you need an explicit interface for *ANY* procedure with an
optional argument. This requirement is not specific to the case of
passing the optionality down the tree.
Note also that you may use either positional or keyword syntax for
the optional arguments (though you can't use a double comma to indicate
an omitted argument). Michael's examples all used the keyword
syntax. The following line would also be valid in Michael's
subroutine first.
call second(a,b,c)
This is ok even if b and c are not present; the non-presense gets
passed down correctly.
One caveat in the general area of optionality: Having an actual
argument that is a nullified pointer is *NOT* the same thing as
omitting the actual argument. There are times when this would be
convenient. Perhaps in some future revision (at least for nonpointer
dummies; making a null actual count as non-present for a pointer
dummy would break existing code).
--
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
Many thanks, this works just fine. However I now have a further issue
where the variables b and c get manipulated into d and e respectively.
The presence or otherwise of b and c decides whether d and e get
calculated. Now I want to call the next routine, third, with d and e
as arguments. I presume I have to do the full check here as per my
first post:
if ( present(b) .and. present(c)) then
call third(a,d=d,e=e)
elseif(.not. present(b) .and. present(c)) then
call third(a,e=e)
elseif( present(b) .and. .not. present(c)) then
call third(a,d=d)
else
call third(a)
endif
Is there a more elegant way of doing this?
Adrian
Well, you could set d and e to some default value that can be tested in
third, which you call with all 3 arguments, something like:
real :: d = huge(0.), e = huge(0.)
:
if (present(b)) d = fn(b)
:
call third(a, d, e)
Hope that helps,
Mike Metcalf