 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Todd Hopfinger Guest
|
Posted: Tue Oct 19, 2004 6:05 pm Post subject: C Style Callbacks |
|
|
I do not understand why C style callbacks are not type safe. A
callback function must match the function pointer signature specified
in the callee. If the signatures are compared at compile time, how is
this not type safe? I understand that a function pointer is just an
address but if the compiler is capable of checking the use of the
callback I don't see how it could not be type safe. Please explain
and provide examples. Thanks!
Todd Hopfinger
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Phlip Guest
|
Posted: Wed Oct 20, 2004 4:29 pm Post subject: Re: C Style Callbacks |
|
|
Todd Hopfinger wrote:
| Quote: | I do not understand why C style callbacks are not type safe. A
callback function must match the function pointer signature specified
in the callee. If the signatures are compared at compile time, how is
this not type safe? I understand that a function pointer is just an
address but if the compiler is capable of checking the use of the
callback I don't see how it could not be type safe. Please explain
and provide examples. Thanks!
|
The callback itself is safe. The environment around the callback is tainted.
Consider this quite traditional callback:
BOOL worked = EnumEnhMetaFile
(
NULL,
metaFile,
metaFileRecordFunction,
&payload,
&aDrawItem.rcItem
);
metaFileRecordFunction is a C-style function:
int CALLBACK
metaFileRecordFunction
(
HDC,
HANDLETABLE FAR *,
CONST ENHMETARECORD *rec,
int,
LPARAM param
)
{
std::wstringstream &payload =
*reinterpret_cast<std::wstringstream*>(param);
....
}
To be non-useless, the authors of the API function EnumEnhMetaFile() had to
provide an extra parameter, which I called 'payload'. The API's only purpose
for that parameter is to pass its 32 naked typeless bits into
metaFileRecordFunction().
(I have written a 460-page apologia for my indenting style, if anyone's
interested ;-)
Once inside metaFileRecordFunction(), before using 'payload, I have to
reconstitute its true type using reinterpret_cast. This is where typesafety
lapses.
Any place you might have a C-style cast, you should only use a C++
elaborate_cast. It will force you to expose the exact degree of typesafety
you lost. Callbacks force these lapses on both sides of their interface,
because they are _only_ typesafe with regards to their basic
function-pointer type.
By contrast, a C++ solution would implement the Abstract Template Pattern
here, and call my callback method with both a data record and a 'this'
pointer, cast by the compiler to the correct type.
--
Phlip
http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jeff Flinn Guest
|
Posted: Wed Oct 20, 2004 4:29 pm Post subject: Re: C Style Callbacks |
|
|
"Todd Hopfinger" <thopfin (AT) msn (DOT) com> wrote
| Quote: | I do not understand why C style callbacks are not type safe. A
callback function must match the function pointer signature specified
in the callee. If the signatures are compared at compile time, how is
this not type safe? I understand that a function pointer is just an
address but if the compiler is capable of checking the use of the
callback I don't see how it could not be type safe. Please explain
and provide examples. Thanks!
|
Because many define their arguments as void*.
Jeff F
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Wed Oct 20, 2004 6:33 pm Post subject: Re: C Style Callbacks |
|
|
Todd Hopfinger wrote:
| Quote: | I do not understand why C style callbacks are not type safe. A
callback function must match the function pointer signature specified
in the callee. If the signatures are compared at compile time, how is
this not type safe? I understand that a function pointer is just an
address but if the compiler is capable of checking the use of the
callback I don't see how it could not be type safe.
|
Your understanding is right, there is nothing type-unsafe in using function
pointers. However, a raw function usually has no or little(and then
global!) own state attached, which is often not sufficient or doesn't fit
the design well.
As a remedy, you not only pass the callback to the library but also some
token which resembles the state/context for that callback. The inherently
type-unsafe thing about this is that, in order to be generic, this context
always has to be a void-pointer.
Uli
--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Kevin Cline Guest
|
Posted: Wed Oct 20, 2004 9:38 pm Post subject: Re: C Style Callbacks |
|
|
[email]thopfin (AT) msn (DOT) com[/email] (Todd Hopfinger) wrote in message
news:<c568d071.0410182142.673bbe68 (AT) posting (DOT) google.com>...
| Quote: | I do not understand why C style callbacks are not type safe. A
callback function must match the function pointer signature specified
in the callee. If the signatures are compared at compile time, how is
this not type safe? I understand that a function pointer is just an
address but if the compiler is capable of checking the use of the
callback I don't see how it could not be type safe. Please explain
and provide examples. Thanks!
|
The C library function qsort has this signature:
typedef int (*comparison_fn_t)(const void *a, const void *b)
void qsort (void *array, size_t count, size_t size, comparison_fn_t
compare)
So if I have:
int compare_int(const void* a, const void* b)
{ int *ia = (int*) a; ... }
and
int compare_double(const void* a, const void* b)
{ double *ia = (double*) a; ... }
Then I can write:
int array[5] = { 17, 3, 44, 0, -5 };
qsort(array, 5, sizeof(int), compare_double); /* oops */
Most C callback functions take at least one void* argument so that
client data can be passed to the callback function.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|