9

Qt documentation says, return values of signals are not possible:

Signals are automatically generated by the moc and must not be implemented in the .cpp file. They can never have return types (i.e. use void).

Related SO questions:

  1. Can Qt signals return a value?
  2. Qt: meaning of slot return value?

However, from my trials (Qt 4.8.1) I can tell return values do work:

  1. If signal / slot are in the same thread, ConnectionType may be Qt::AutoConnection
  2. With signal / slot in different threads I need to use Qt::BlockingQueuedConnection

So in my code I call a signal by

QString dp = emit WscAircrafts::signalAircraftsJsonArray();

and the signal moc returns a QString,

QString _t0;
void *_a[] = { const_cast<void*>(reinterpret_cast<const void*>(&_t0)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
return _t0;

This here is the slot moc where it passes back the QString

case 4: { QString _r = _t->slotAircraftJsonArray();
  if (_a[0]) *reinterpret_cast< QString*>(_a[0]) = _r; }  break;

All of this seems to be pretty much straight forward, so why this contradiction with the documentation? Where would be the problem using the return value? As said, in my code this seems to work.

Community
  • 1
  • 1
Horst Walter
  • 13,663
  • 32
  • 126
  • 228
  • 3
    what happens if the signal is connected to multiple slots? – Martin Beckett Aug 09 '12 at 19:44
  • 2
    In another similar question answer it says: "Seems this is possible. I was able to emit a signal, and receive value from the slot the signal was connected to. But, the problem was that it only returned the last return value from the multiple connected slots". Must be the reason why they dont want to advertise this feature – Roman Saveljev Aug 09 '12 at 19:45
  • @RomanSaveljev - would it also have to block until the slot had completed? – Martin Beckett Aug 09 '12 at 19:48
  • There are certainly situations where this cannot work. But in most cases this depends on how you set the connection. E.g. with Qt::SingleConnection there is no risk of multiple slots, with Qt::BlockingQueuedConnection there is only one return value at a time. "Never have a return value" (doc) is different to use wisely IMHO. All the above true, there might be side effects, but still many use cases where return values are very useful. – Horst Walter Aug 09 '12 at 19:51
  • 2
    Even if possible it might not be desirable since it violates the commmand query separation principle. In other words, signals that return values might make your program hard for readers to understand and reason about. Most readers might expect a signal to be a command. Signals decouple, but signals that return values are less decoupled. – bootchk Mar 11 '13 at 13:19
  • Yes this is true, however do I not couple explicitly by setting Qt::BlockingQueuedConnection? – Horst Walter Mar 11 '13 at 13:47

1 Answers1

5

The problem is that the return types are are not checked for compatibility at connect-time, thus connecting a double-returning slot to a float-returning signal, say, will overflow the stack (no pun intended) space allocated to the float.

Marc Mutz - mmutz
  • 24,485
  • 12
  • 80
  • 90
  • But this would also mean, if the return types fit and everything is done correctly it will be no problem to use them. – Horst Walter Sep 10 '13 at 15:04
  • 1
    @HorstWalter yes, unless the connection is queued (in which case the deferred slot invokation might clobber long-freed memory, but I haven't checked that deeply) or there's more than one slot connected to the signal (in which case you'd only get the last slot's result). – Marc Mutz - mmutz Sep 10 '13 at 15:19