PDA

View Full Version : How Signal/slot is type-safe????



Shuchi Agrawal
9th March 2007, 09:54
Hi all,
Can any one please help me in understanding( may be with an example) that how callbacks are not type safe and how Qt's signal/slot overcome this or can say that how Qt's signal/slot is typesafe?
i may be wrong. so plz correct me if i m badly gng out of track. C callbacks are not typesafe but c++ callbacks are type safe, so as Qt is a C++ GUI toolkit, it is typesafe?

wysota
9th March 2007, 10:55
Hi all,
Can any one please help me in understanding( may be with an example) that how callbacks are not type safe
When you register a callback in C, it is usually by passing a void * pointer (or a function pointer) to a register function. The problem is that you can pass a pointer to any function, even one that has completely different arguments than the callback mechanism expects. When such a method is then called, it can assume a completely different stack frame and either corrupt the frame or rely on a bogus return address (or both). In all cases it'll at least cause the application to crash.


and how Qt's sagnal/slot overcome this or can say that how Qt's signal/slot is typesafe?
Qt does a signature check upon making the connections (that's essentially what moc is for) and does that without relying on types of pointers or anything like that but on the textual code generated by moc (open some moc_*.cpp file in your text editor and see what's inside).


C callbacks are not typesafe but c++ callbacks are type safe, so as Qt is a C++ GUI toolkit, it is typesafe?

C++ "callbacks" are most often realised by reimplementing some virtual method (like with all event handlers in Qt), therefore it's type safe, as you can't modify the argument list of such a method (if you do, you'll create a different method instead of overriding the base class implementation).

Shuchi Agrawal
9th March 2007, 11:36
Thanks a lot.
But i still have some doubts.
Following is some code for a callback approach :

/* LIBRARY CODE */
int traverseWith(int array[], size_t length,
int (*callback)(int index, int item, void *param),
void *param)
{
int exitCode = 0;
for(int i = 0; i < length; i++)
{
exitCode = callback(i, array[i], param);
if(exitCode)
{ break; }
}
return exitCode;
}

/* APPLICATION CODE */
int search(int index, int item, void *param)
{
if(item > 5)
{
*(int *)param = index;
return 1;
}
else
{ return 0; }
}

/* (in another function) */
int index;
int found;
found = traverseWith(array, length, search, &index);
if(found)
{
printf("Item %d\n", index);
}
else
{
printf("Not found\n");
}

Can u please read the code and explain that how this code can be type-unsafe in c or C++
and how it can b type-safe in Qt.

wysota
9th March 2007, 12:16
int (*callback)(int index, int item, void *param)
This is a signature of a callback function pointer returning an int and taking two ints and a void*.
If I'm correct you could do the following:

typedef int (*callback)(int index, int item, void *param) CALLDEF;
void dummy(){

}

found = traverseWith(array, length, (CALLDEF)dummy, &index);
I cast the functor to a type the "traverseWith" function expects so the compiler shouldn't interfere. And when you call the above line, the compiler will create a frame stack for a method that expects a return value and has three arguments. But the function which actually is called expects a completely different frame stack, which will lead to stack corruption and a crash.

In C++ you'd use function objects based on templates, which do type checking, etc. making it a bit safer (you pass around objects and not pointers). Qt uses a simmilar approach (for example when sorting).

Shuchi Agrawal
9th March 2007, 12:38
ok. thats fine. so am i right if i say that signal/slot is type safe because of C++ type safe ability?
fm the above explanation, can i say that it depends on the use that how one code. we can make all type safe if we code properly?

wysota
9th March 2007, 12:54
so am i right if i say that signal/slot is type safe because of C++ type safe ability?
No. Signals and slots use a completely different mechanism. They are type safe because each signal and slot has a textual signature which is checked and compared to the other signature during connection, so it is Qt that assures that appropriate methods get connected. C++ has nothing to do with that.


fm the above explanation, can i say that it depends on the use that how one code. we can make all type safe if we code properly?
In the simplest cases, yes.
But the example you provided is not exactly what I'd call a callback. If you use C++, you should avoid such constructions in favour of using classes.

Brandybuck
10th March 2007, 04:59
i may be wrong. so plz correct me if i m badly gng out of track. C callbacks are not typesafe but c++ callbacks are type safe, so as Qt is a C++ GUI toolkit, it is typesafe?
Yes, Qt's signals are typesafe. When the connect() call is made, to connect a signal to a slot, the parameters are strictly checked. This is done at runtime, not compile time, so you get the advantage of type safety with runtime objects, which are great for components and plugins.

But there's more than just type safety. When you get to OO and C++, you encounter a new problem which I call the "dangling callback" problem. Unfortunately, this is all too common in GUI toolkits. You invokde a callback method, but the object has been destroyed, and so you get a memory fault.

But Qt's signal/slots are safe here as well. You cannot get a dangling callback, because Qt does not use callbacks internally. You can safe emit a signal even if all the objects with connected slots have been destroyed. There is no problem.