comp.lang.ada
 help / color / mirror / Atom feed
From: taashlo@sandia.gov
Subject: Re: How to Emulate C++ Macro with Static Local Variable?
Date: 30 Sep 2003 07:02:44 -0600
Date: 2003-09-30T07:02:44-06:00	[thread overview]
Message-ID: <uy8w6mnt7.fsf@sandia.gov> (raw)
In-Reply-To: b35eb.8293$RW4.197@newsread4.news.pas.earthlink.net

Jeffrey Carter <spam@spam.com> writes:
> taashlo@sandia.gov wrote:
> > Jeffrey Carter <spam@spam.com> writes:
> >
> >>>1) Use a unique ID for each call.  But this turns into a maintenance
> >>>nightmare when you get a few hundred calls or more.
> >>>2) Use the return address of the call.  But there was a short
> >>>discussion
> >>>about how Ada doesn't currently have a way of accessing the return
> >>>address of a subprogram.
> >>
> >>3. Use a unique instantiation of a generic package for each call. The
> >>instantiations of the package must be at a nesting level that ensures
> >>that they will exist for the entire lifetime of the executable region
> >>in which they are used.
> > Won't a unique instantiation require a unique name?  This is the same
> > problem with item 1) above.  A single unique instantiation is no
> > problem, but try a thousand instantiations whose associated function
> > calls are scattered across fifty files.  Where using the wrong
> > instantiation can lead to subtle and difficult-to-reproduce errors.
> > This is not a solution that I'd voluntarily aim for.
> 
> We've gone from hundreds to thousands now? I can play that game,
> too. If you use millions of identical calls in your code, no one can
> maintain it, no matter what language or technique you use.

I went up one order of magnitude, you went up four.  You appear to play
the game much better than I. :-)

> There are significant differences between using a unique ID and a
> unique instantiation name. With IDs you have to add new IDs and modify
> the code that interprets the ID as well as insert the new call for a
> new location.

If the ID is simply an index into an array of caches, it doesn't require
you to "modify the code that interprets the ID".  So it's down to "add
new IDs" and "insert the new call".

> With an instantiation you add the new instantiation and
> the new call.

Same as above.  Please give more detail on the "significant
differences".

> You need never touch the existing code except to delete
> a call, and that, of course, is true regardless of the technique
> used.

But don't forget to delete the associated generic instantiation, too.

> With a good process for choosing the next instantiation name,
> you'll never create a problem.

I don't know of a manual process that can prevent me from being human
and therefore making mistakes.  And the penalty for making a mistake of
accidentally re-using an instantiation name is that the location that
gets called first will determine the contents of the cache for both
locations.  In a dynamic system where the one that gets called first
changes from execution to execution, this could result in a *very*
difficult bug to find.

> All this is sort of irrelevant, though. We don't know what you're
> trying to accomplish, just a technique you're trying to use. Without
> that knowledge, we can't really tell how to advise you.

In another posting, I did explain what I was trying to accomplish.  (I
didn't post it originally because I was afraid that the discussion would
get sidetracked for various reasons.)

I'm attempting to port a C++ library that supports implementing
hierarchical state machines (think UML statecharts) directly in a
programming language (as opposed to using a tool to generate the code).
The function in question performs a state transition.  You pass in the
target state and it discovers the path from the current state to the
target state.  It then caches this information so that subsequent calls
from the same location don't need to perform the same "discovery"
process.

Yes, the transition path could (possibly) be cached by the state
transition function based on the starting state and the target state.
(In Ada, is it possible to somehow use the *value* of subprogram access
parameters?  In this system, a state is defined as a subprogram access
type.)  You can use dynamic allocation.  Or you can reserve enough space
so that you can cache all state transitions.  Or you can can have some
combination of both so that when the reserved space is filled, more will
be allocated.  Or you can come up with more options that I haven't
thought of yet.  And if I was just developing an application, a large
number of choices is great.  But for porting a library whose utility
ranges from GUI applications running on workstations to small embedded
systems, having to make a choice will certainly narrow this range.  And
it won't win me any converts from C++ because the C++ implementation
didn't require you to know ahead of time how many state transitions
there are, or suffer the overhead of dynamic allocation, or have to come
up with a unique name for each cache.

One solution would be to come up with a way to automatically pre-cache
the state transitions during initialization.  This way, you could
statically reserve cache space and if you didn't have enough cache space
reserved, you would find out during start-up.  I'll look into this.

> --
> Jeff Carter
> "You've got the brain of a four-year-old boy,
> and I bet he was glad to get rid of it."
> Horse Feathers
> 47

BTW, if you have 50 state machines (which is reasonable for a
medium-large system) times 20 state transitions per state machine (some
will have more, some less, but this sounds reasonable to me) gives 1000
calls to the state transition function.

Tad



  parent reply	other threads:[~2003-09-30 13:02 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-09-24 22:06 How to Emulate C++ Macro with Static Local Variable? taashlo
2003-09-24 23:44 ` Robert I. Eachus
2003-09-25  3:27   ` Hyman Rosen
2003-09-25  4:53     ` tmoran
2003-09-25 15:57       ` Robert I. Eachus
2003-09-25 19:09         ` tmoran
2003-09-29 14:57           ` taashlo
2003-09-29 18:12             ` Jeffrey Carter
2003-09-29 18:51               ` taashlo
2003-09-30  1:32                 ` Jeffrey Carter
2003-09-30  1:54                   ` tmoran
2003-09-30 13:02                   ` taashlo [this message]
2003-09-30 20:25                     ` Jeffrey Carter
2003-09-30  2:45             ` Robert I. Eachus
2003-09-30  3:24               ` tmoran
2003-09-25 13:43     ` Stephen Leake
2003-09-25 12:59   ` Tad Ashlock
2003-09-25 16:11     ` Robert I. Eachus
2003-09-25 18:13       ` Randy Brukardt
2003-09-25 23:40         ` Robert I. Eachus
2003-09-25 11:54 ` Gautier
2003-09-25 16:14   ` Robert I. Eachus
2003-09-25 18:06   ` Tad Ashlock
2003-09-28  8:42     ` Gautier Write-only
2003-09-28 20:06       ` Jeffrey Carter
2003-09-29  2:13         ` Gautier Write-only
2003-09-25 13:41 ` Stephen Leake
2003-09-25 17:23   ` Tad Ashlock
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox