M
Mark Piffer
Hi group,
only today I stumbled over the famous (?) inability of C to define
recursive types for functions.
The task was to define a daisy chain of functions which facilitate
insertion and deletion by
passing and returning function pointers of their very own type. Each
function should hold
a static variable to its' successor. After having unwound my brain
from the infinite recursion
that happened in the first typedef (*)()(*foo)((*)(...etc. I rummaged
the comp.lang.c archives
and found the explanation with a workaround based on structs. I
remember however that
function pointers can be cast into one another and back without
invoking undefined behaviour.
Is this solution any worse than the struct thing? (code not yet
checked for logical errors, but
it compiled ok on Comeau):
typedef int (*mock_func_ptr)();
typedef mock_func_ptr (*daisychain_func_ptr)();
daisychain_func_ptr
me(daisychain_func_ptr new_func)
{
daisychain_func_ptr next;
int call_me_again;
/* do something useful here...*/
if (call_me_again) {
if (!next) {
next = (daisychain_func_ptr)new_func(0);
}
else {
next = (daisychain_func_ptr)next(new_func);
}
return (daisychain_func_ptr)me;
}
else {
if (next) {
daisychain_func_ptr t = next;
next = 0;
return (daisychain_func_ptr)t(new_func);
}
else if (new_func) {
return (daisychain_func_ptr)new_func(0);
}
else {
return 0;
}
}
}
only today I stumbled over the famous (?) inability of C to define
recursive types for functions.
The task was to define a daisy chain of functions which facilitate
insertion and deletion by
passing and returning function pointers of their very own type. Each
function should hold
a static variable to its' successor. After having unwound my brain
from the infinite recursion
that happened in the first typedef (*)()(*foo)((*)(...etc. I rummaged
the comp.lang.c archives
and found the explanation with a workaround based on structs. I
remember however that
function pointers can be cast into one another and back without
invoking undefined behaviour.
Is this solution any worse than the struct thing? (code not yet
checked for logical errors, but
it compiled ok on Comeau):
typedef int (*mock_func_ptr)();
typedef mock_func_ptr (*daisychain_func_ptr)();
daisychain_func_ptr
me(daisychain_func_ptr new_func)
{
daisychain_func_ptr next;
int call_me_again;
/* do something useful here...*/
if (call_me_again) {
if (!next) {
next = (daisychain_func_ptr)new_func(0);
}
else {
next = (daisychain_func_ptr)next(new_func);
}
return (daisychain_func_ptr)me;
}
else {
if (next) {
daisychain_func_ptr t = next;
next = 0;
return (daisychain_func_ptr)t(new_func);
}
else if (new_func) {
return (daisychain_func_ptr)new_func(0);
}
else {
return 0;
}
}
}