Re: legality of signature changes of callback functions
- From: regis <regis@xxxxxxxxxxxxxxx>
- Date: Thu, 20 Mar 2008 22:25:24 +0100
Eric Sosman wrote:
regis wrote:
Hello,
Suppose that some type of callback function is declared
to take a pointer to some struct as one of its argument.
Is it legal to implement the callback functions as
taking a void* for this argument.
No. (Usually the question is asked the other way
around, but the answer is still No.)
Reason: If you call a function via a function pointer
whose type does not match that of the called function,
the behavior is undefined.
Rationale: The caller builds an argument list that
matches the caller's idea of what the called function
expects to receive. If the called function expects one
thing and the caller has set things up differently, it's
anybody's guess what might happen.
Practicality: On many machines it will turn out that
"all pointers smell the same," meaning that they have the
same representation and are passed to functions by the
same conventions. So you're likely to get away with it --
until, in the words of the Sixth Commandment, "the day
before thy Thesis Oral or thy Big Pitch To The Client."
ok, thank you.
(The context is that I am sometimes fed up
with all those casts in gtk and I wonder if it is
legal to replace GtkWidget* arguments of callback functions
by void* directly in the signature of the callbacks)
I'm not familiar with GTK, but this seems backwards:
Something in GTK passes one of your functions a GtkWidget*,
and you want to transform this to a void*? That is, you
want to throw away the information about the type of the
thing it points to? Sounds bizarre: More commonly, one
receives a void* from a type-ignorant caller, and then
converts it to a Something* to add type information. It's
not so usual to want to destroy type information, so I sort
of wonder what you're up to ...
I wanted to avoid to constantly cast pointers
to match the signature of the functions called inside the callback:
for example, given...
typedef struct { ... } Foo1;
typedef struct { Foo1 foo1; ...} Foo2;
typedef struct { Foo2 foo2; ...} Foo3;
typedef void (* Callback2) (Foo2*, void*)
void some_function1 (Foo1 * f);
void some_function2 (Foo2 * f);
void some_function3 (Foo3 * f);
.... a callback will typically have to downcast or upcast
its argument to functions called inside it:
void some_callback2 (Foo2 * f, void * data) {
some_function2 ( f);
some_function1 ((Foo1*) f); /* upcast needed */
some_function3 ((Foo3*) f); /* downcast needed */
}
.....So, the first step was to re-write it as:
void some_callback2 (Foo2 * f, void * data) {
void * v= f;
some_function2 (v);
some_function1 (v); /* no upcast needed */
some_function3 (v); /* no downcast needed */
}
.... and I wondered if I could re-re-write it directly as:
void callback (void * f, void * data) {
some_function2 (f);
some_function1 (f);
some_function3 (f);
}
.... but obviously, I can't do this last step,
because your answer was that it was a constraint violation.
--
regis
.
- Follow-Ups:
- Re: legality of signature changes of callback functions
- From: Richard Bos
- Re: legality of signature changes of callback functions
- From: Eric Sosman
- Re: legality of signature changes of callback functions
- References:
- legality of signature changes of callback functions
- From: regis
- Re: legality of signature changes of callback functions
- From: Eric Sosman
- legality of signature changes of callback functions
- Prev by Date: Re: K&R Errata?
- Next by Date: Re: K&R Errata?
- Previous by thread: Re: legality of signature changes of callback functions
- Next by thread: Re: legality of signature changes of callback functions
- Index(es):
Relevant Pages
|