I am working with Qt for some time, and I still wasn't able to understand properly if it is safe to use references in signals and slots.
In my understanding, it is unsafe, because if a connection is not direct (signal in one thread, slot in another) — then this reference will be "remembered" in some intermediate object, and it will become dangling. However, if a connection is direct, it should be pretty safe.
There are no warnings in Qt Creator when I am using references, and also, it seems to work even when I tried to artificially create a situation where the passed object is dead before the slot is called. It seemed to work fine. Maybe it is because Qt somehow handles my references internally and still copies this object?
So, my question is: is it safe? Even if it is safe, should I do it? Are there any "best practices" for it?
The following blog post contains an extended answer and explanation https://embeddeduse.com/2013/06/29/copied-or-not-copied-arguments-signals-slots/.
TLDR. Qt connections can either be Direct
(default when signal and slot are emitted/received in the same thread) or Queued
(default when signal is emitted in one thread and the slot receives it in another). In a Direct
connection Qt behaves as expected with the usual C++ semantics (i.e. pass-by-value gets copied, references do not). In a Queued
one a copy is always made no matter what the (const)refness of the actual type provided is.
To answer your question, it seems that the reference going out of scope in which the connection is Direct
would lead to UB. Note that depending on your example this would not necessarily always lead to a crash - it could well be that the reference is dangling but the memory it points to is still valid.
As for the best practices, the blog post suggests always using const ref in both the signal and the slot as that minimizes copies. Since it's ~10 years old however, I'd be keen to repeat the experiment described in it before completely trusting the results. I'd do it myself but I don't have Qt installed anywhere currently - might come back at a later date and post a comment with the results.
More about Qt connection types and their behaviour can be found here https://doc.qt.io/qt-6/qt.html#ConnectionType-enum.