Thorsten Ohl wrote:
> [...]
> I hope this is not insulting to a compiler writer, but for me it is
> really important that a compiler can handle all the nitty-gritty
> (and sometimes boring) details that are highly error prone.
> [...]
For this given example, I would think the underneath _design_ of the
procedure inject_division_s() to be the source of the complexity. With
three optional arguments, inject_division_s() would have to handle
them either a) linearly, or b) exponentionally. It may be even
possible that some combinations of all 2^3 possibilities never
occur in the reality.
If inject_devision_s() handle the options linearly, then there
must be some better way to design the code such that the parent
procecure inject_devision_v() won't have to handle the optional args.
exponentially.
Another possibility is to have only selected versions of the
vector procedure inject_division_v() with reduced number of
optional arguments for specific but not so generic applications.
In cast that you can not or no intention to modify the _design_ of
inject_division_s(), I would suggest a style change just for this
case, such that with simple cut-and-pastes, a more compact and
not so error prone implementation could be produced in minutes:
...
integer,dimension(:),optional,intent(in) :: cell
integer,dimension(:),optional,intent(out) :: idx
real, dimension(:),optional,intent(out) :: x_mid
integer,parameter :: cmask=100 ! no need for binaries
integer,parameter :: imask=010
integer,parameter :: xmask=001
integer :: mask
! Verify the presence of optional arguments _linearly_
mask=000
if(present(cell )) mask=mask+cmask
if(present(idx )) mask=mask+imask
if(present(x_mid)) mask=mask+xmask
do i=1,size(d)
! A complete list of _all_ cases!
select case(mask)
case(000)
call inject_...(... )
case(001)
call inject_...(..., x_mid=x_mid(i))
case(010)
call inject_...(..., idx=idx(i) )
case(011)
call inject_...(..., idx=idx(i),x_mid=x_mid(i))
case(100)
call inject_...(...,cell=cell(i) )
case(101)
call inject_...(...,cell=cell(i), x_mid=x_mid(i))
case(110)
call inject_...(...,cell=cell(i),idx=idx(i) )
case(111)
call inject_...(...,cell=cell(i),idx=idx(i),x_mid=x_mid(i))
case default
stop "It is the end of the world!"
end select
end do
...
By shortening the local names, the implementation could be more
compact to handle 4 (16 calls) or more optional arguments.
Jing
--
________________________________ _-__-_-_ _-___---
Jing Guo, [log in to unmask], (301)805-8333(o), (301)805-7960(fx)
Data Assimilation Office, Code 910.3, NASA/GSFC, Greenbelt, MD 20771
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|