I
I.M. !Knuth
A while back, I was mucking around with a recursive function. For
brevity's sake, I'll define it like this:
int func_recurs(int arg1, int arg2, int prev_pos)
{
int crnt_pos = 0;
int result;
/* stuff happens to arg1, arg2, and crnt_pos */
func_recurs(arg1, arg2, (prev_pos + crnt_pos) );
return result;
}
The critical part here (as I'm sure you've figured out already) is that
prev_pos (the previous position) of the last recursion is combined with
crnt_pos (the current positon) of the present recursion and passed along
to become the prev_pos of the next recursion.
But written this way, I had to remember that any call to func_recurs()
always had to look like this:
func_recurs(arg1, arg2, 0);
Frankly, I thought that constant 0 dangling at the end was rather
inelegant. Then it struck me that maybe I could "hide" func_recurs
inside another function so that I wouldn't have to strain my brain
remembering about that pesky third argument; something like:
func_lazymemory(int arg1, int arg2)
{
func_recurs(arg1, arg2, 0);
}
Being new to C, I felt pretty clever for coming up with this all on my
own. But then I thought: "Bah! Smells of kludge. There must be a
better way."
So I changed it to:
int func_recurs(int arg1, int arg2)
{
--> static int prev_pos; /* conveniently init'd to 0 on 1st call */
int crnt_pos = 0;
int result;
/* stuff happens to arg1, arg2, and crnt_pos */
--> prev_pos += crnt_pos; /* adjust for next recursion */
--> func_recurs(arg1, arg2);
--> prev_pos -= crnt_pos; /* restore for current recursion */
return result;
}
Drawing your attention to the four "-->" lines, I then thought: "Boy is
that ugly", but I no longer felt I'd somehow cheated inside my code. I
packed away the function and forgot about it ... until tonight.
Tonight I was browsing through some months' old threads on clc and came
across one that discussed function wrappers. "Cool," I thought. A
response referenced the FAQ, so I pulled it up and had a read. So, my
clever idea is old hat. Figures! :-D
I started thinking again about how I dealt with that function and came
up with some questions and concerns:
1a) Is my use of a wrapper appropriate (or am I ignorant of some wrapper
rule or style convention)?
1b) Wouldn't the wrapper be improved (and the program conserve some
storage) if it were re-written to pass pointer values like this?
func_lazymemory(int *arg1, int *arg2)
{
func_recurs(arg1, arg2, 0);
}
2a) Is one of my solutions better/cleaner/preferable over the other?
2b) Or are they equivalent, and picking one is a matter of (my) personal
style?
3) Is there some other (maybe obvious) solution to ditching that third
argument that I've somehow overlooked?
Thanks for your attention.
brevity's sake, I'll define it like this:
int func_recurs(int arg1, int arg2, int prev_pos)
{
int crnt_pos = 0;
int result;
/* stuff happens to arg1, arg2, and crnt_pos */
func_recurs(arg1, arg2, (prev_pos + crnt_pos) );
return result;
}
The critical part here (as I'm sure you've figured out already) is that
prev_pos (the previous position) of the last recursion is combined with
crnt_pos (the current positon) of the present recursion and passed along
to become the prev_pos of the next recursion.
But written this way, I had to remember that any call to func_recurs()
always had to look like this:
func_recurs(arg1, arg2, 0);
Frankly, I thought that constant 0 dangling at the end was rather
inelegant. Then it struck me that maybe I could "hide" func_recurs
inside another function so that I wouldn't have to strain my brain
remembering about that pesky third argument; something like:
func_lazymemory(int arg1, int arg2)
{
func_recurs(arg1, arg2, 0);
}
Being new to C, I felt pretty clever for coming up with this all on my
own. But then I thought: "Bah! Smells of kludge. There must be a
better way."
So I changed it to:
int func_recurs(int arg1, int arg2)
{
--> static int prev_pos; /* conveniently init'd to 0 on 1st call */
int crnt_pos = 0;
int result;
/* stuff happens to arg1, arg2, and crnt_pos */
--> prev_pos += crnt_pos; /* adjust for next recursion */
--> func_recurs(arg1, arg2);
--> prev_pos -= crnt_pos; /* restore for current recursion */
return result;
}
Drawing your attention to the four "-->" lines, I then thought: "Boy is
that ugly", but I no longer felt I'd somehow cheated inside my code. I
packed away the function and forgot about it ... until tonight.
Tonight I was browsing through some months' old threads on clc and came
across one that discussed function wrappers. "Cool," I thought. A
response referenced the FAQ, so I pulled it up and had a read. So, my
clever idea is old hat. Figures! :-D
I started thinking again about how I dealt with that function and came
up with some questions and concerns:
1a) Is my use of a wrapper appropriate (or am I ignorant of some wrapper
rule or style convention)?
1b) Wouldn't the wrapper be improved (and the program conserve some
storage) if it were re-written to pass pointer values like this?
func_lazymemory(int *arg1, int *arg2)
{
func_recurs(arg1, arg2, 0);
}
2a) Is one of my solutions better/cleaner/preferable over the other?
2b) Or are they equivalent, and picking one is a matter of (my) personal
style?
3) Is there some other (maybe obvious) solution to ditching that third
argument that I've somehow overlooked?
Thanks for your attention.