[Interest] QMetaMethod::invoke / Q_ARG with a temporary

Richard Weickelt richard at weickelt.de
Mon May 7 22:06:35 CEST 2018


> today I discovered that Q_QArgument does not handle a temporary (boolean)
> value as I would have expected it.
> I'm invoking the method similar to this:
> 
> QArgument<bool> arg3("bool", !inProgress);
> request.replySlot.invoke(m_objToInform, Qt::QueuedConnection, arg1, arg2,
> arg3);

I think your expectation is wrong. QArgument does not store the value, but
the value's location. The lifetime of !inProgress does not exceed
QArgument's constructor and hence, !inProgress does not exist anymore after
above line.

If it works for direct connections, then this is only luck because the
temporary variable !inProgress might still exist.

> Changing it to
> bool bFinished = !inProgress;
> QArgument<bool> arg3("bool", bFinished);
> fixes the problem but I'm not sure if the compiler can maybe optimize it
> away...> I did not found a hint int the documentation about this behavior. Therefore
> my question - should this work for a queued connection or not? At least
> msvc2017 and gcc 4.8 don't like it when compiling with -O2...

I haven't looked at the implementation of asynchronous signals and slots,
but I would guess that Qt caches only the QArgument object (the one that
contains the pointer to the data). Thus, the variable bFinished must exist
physically in the moment when the slot is invoked. I think you need to move
your variable to the heap if the slot is invoked after the current stack
context is left.

Richard



More information about the Interest mailing list