Mr. Ed said:
Wow - I hadn't realised that my use of a forbidden word would stir up
such a hornet's nest. Perhaps I could rephrase the problem in an
acceptable manner. Assume that I have a routine that does this:
Now, also assume that for ideological reasons, I don't like to use
static variables. If you like, you can also imagine that I am
executing in an environment in which the keyword 'static' ensures that
this code won't work; it doesn't matter whether this is actually the
case, or why it won't work if this does happen to be the case.
Problem: is there a way to reformulate 'get_unique_id' so that:
1) 'id' is not in static storage; it should be on the stack somewhere
2) 'id' retains a memory of its value between function calls
3) The interface to 'get_unique_id' is unchanged
At first sight, this doesn't seem to be possible. The only obvious
solution is for the caller to save the current 'id' on their own
stack, and for 'get_unique_id' to increment it, but this isn't
possible because of constraint (3).
Any ideas?
How about an idea for an impossibility proof? Would that
make you happier? Here's a sketch:
Because the function is forbidden to use static variables
(by which I assume you mean "objects with static storage
duration, whether or not the `static' keyword is used"), it
can only access its own arguments and its own `auto' and
`register' variables. By constraint (3) there are no arguments,
and the other two possibilities do not meet the requirements
of constraint (2).
Dynamically-allocated storage won't help, because to make
use of its persistence (until freed) you'd need to communicate
a pointer value from one function invocation to another. The
argument above shows that no suitable channel exists -- and
besides: we know you're looking for re-entrancy, and malloc()
is not re-entrant. Nor, for that matter, are time() and clock()
and getc() and getenv() and any other Standard C library functions
you might use to query the state of the universe. No, not even
rand() is available.
You could form a pointer to an `auto' variable and try to
deduce something about the state of the stack. However, the C
Standard doesn't guarantee that `auto' variables reside on "the"
stack, nor even on "a" stack (although it's common implementation
practice). Besides, the only thing you can do with a pointer to
an `auto' variable is use it to refer to that variable, and do
a little simple arithmetic on the pointer -- the moment you start
trying to probe outside the `auto' variable itself, you're in the
land of undefined behavior. You certainly cannot use a pointer
to an `auto' variable to somehow locate a variable that belongs
to some caller somewhere.
So: Are you going to look for other approaches (several
have been suggested, but you're being so coy about your intent
that it's hard to choose between them), or are you going to
keep on trying to pound nails with a hacksaw?