This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[OT] cure for nasty #ifdef's?
- From: Tom Roche <Tom_Roche at pobox dot com>,
- To: fortran at gcc dot gnu dot org,
- Date: Wed, 23 May 2012 19:09:09 -0400
- Subject: [OT] cure for nasty #ifdef's?
- Reply-to: fortran at gcc dot gnu dot org, Tom Roche <Tom_Roche at pobox dot com>
I'm pretty sure this is off-topic for this list (feel free to point me
toward something more generally about fortran), but I figure folks on
this list are likely to have answers (esp multi-platform coders):
I work on an atmospheric model (now a family of models--more below),
the code for which long predates me. (We've not yet gotten it to F90.)
Like most Earth-system models it defines a 3-space over the surface of
an Earth region, and various variables of interest within each "box" in
that space, and then solves differential equations over discrete
"timesteps."
One area in which we advance is by creating "instrumented models" (IMs)
derived from our "base model." E.g., we have a sensitivity model which
essentially calculates derivatives of change in one quantity vs
change(s) in one or more other quantities, in each box over each
timestep. (E.g., one might be interested in the sensitivity of
production of ozone to concentrations of other chemical species at
various spacetimes.) Currently, this IM is developed as a separate
body of code, in a separate repository: its developer takes the current
version of the "base model", and adds necessary data structures and
calculations.
The other instrumented models (I believe we currently have 5) proceed
similarly. Note each IM has well-separated concerns:
* our IMs are purely additive: they only add code to the base model,
never subtract.
* our IMs are orthogonal: users can't (yet :-) simultaneously run a
combination of 2 or more IMs.
Separate development means each IM developer spends most of her/his
time "catching up" to changes in the base model. So we'd like to,
jointly,
* have all the developers work on one set of codes
but
* (continue to) have users run only the model of interest
* pay no runtime performance penalty
How best to do this? My group seems to concur that
1 We should make the model-choice @ compiletime. I.e., the user builds
only the model(s) of interest.
2 The only way to do this (of which we're aware, in fortran--more
below) in one set of code is to use the preprocessor. E.g., for
IMs={foo, bar},
#ifdef foo
SUBROUTINE VDIFF ( CGRID, JDATE, JTIME, TSTEP,
& SENGRID, NPMAX, IPT, IPARM, ISPLIT,
& ILAYER, STDATE, IDATE, ITIME, SEN_PAR )
#elif bar
SUBROUTINE VDIFF ( CGRID, JDATE, JTIME, TSTEP,
& HGGRID, HGMAX, HGMIN, HGDATE, HGTIME, HGPAR )
#else
C the base model
SUBROUTINE VDIFF ( CGRID, JDATE, JTIME, TSTEP )
#endif
3 For all but the most trivial blocks (like the above), using the
preprocessor would tend to degrade maintainability, e.g., the code
would quickly get unreadable.
I'd appreciate "second opinions" from outside my group about how to do
this. (And feel free to say, "your analysis is flawless--you're
totally screwed" :-)
Regarding 1: can one make the choice of model/code @ runtime, without
paying a penalty at either buildtime (these models already require
nontrivial time and expertise to build) or runtime (e.g., bloating the
executable)?
Regarding 2: is there an alternative to the preprocessor? E.g.:
I spent a long time coding java; in a similar circumstance there,
I'd try AspectJ or other vehicle for aspect-oriented programming.
I believe there are attempts at AOP for C++, but know of nothing for
fortran. Am I missing something?
Regarding 3: is the readability concern warranted? or will we "just
get over it"?
Again, if there's a better vehicle for questions like this, please
pass a pointer; otherwise,
your assistance is appreciated, Tom Roche <Tom_Roche@pobox.com>