From: http://doc.qt.nokia.com/4.7/signalsandslots.html
Callbacks have two fundamental flaws: Firstly, they are not type-safe. We can never be certain that the processing function will call the callback with the correct arguments.
Can someone explain me, in what kind of situations it is not certain that the arguments won't be correct? What is the technical gist of that statement?
EDIT 1 As pointed out by Gui13 in the below post, the QString does give an error, when a char* is passed instead. But I tested the following program:
#include <iostream>
#include <QString>
#include <stdio.h>
typedef int (*callback_function)( QString *string);
int MyCallback( std::string string )
{
if (string.empty() == false)
std :: cout << string.length();
return 0;
}
int main ()
{
/* in another function */
char *badQstring = (char*)"Booohhh";
MyCallback( (std::string )badQstring );
}
It works properly. Does this mean that Qt's has some problems w.r.t callbacks and this does not imply that the flaw mentioned above is in plain C++ too or I am barking at the wrong tree?
Well, say Qt wants you to give him a callback that takes a pointer to a QString as its argument: your C++ typedef for the call back will look like:
Now, when this callback is called, you can never be sure that the argument passed is really a QString: in C++, this statement is valid and will very likely crash your callback:
Since C++ allows casting, you can never be sure of what type is actually passed to your callback. But, well, this statement is valid to whatever function, even if not a callback.
Please look at
sqlite3_exec()
as a good example. It'svoid*
parameter is a pointer to a "context object" that is passed into the callback function when the latter is called. It's totally up to the user to be sure that thisvoid*
points to a type he expects.For example, you need some complex class as a "context object". You pass an address of an object of that class into
sqlite3_exec()
and it's implicitly converted intovoid*
, then when your callback is called you have to cast it back fromvoid*
and noone catches you if you cast it to the wrong type.It's a pointer to a function, and some compilers don't check that in run time there won't be a case where that pointer leads to a function with different parameters than expected.