Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Why Q_GADGET is not moved?

Why Q_GADGET is not moved?

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 427 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Dmitriano
    wrote on last edited by Dmitriano
    #1

    I have a C++ function that returns a gadget:

    class ZResult
    {
        Q_GADGET
        ...
    };
    
    Q_INVOKABLE ZResult findPeaks();
    

    When the function is called from QML

    var result = market.findPeaks()
    

    ZResult's copy constructor is called. Why is not it moved?

    see the call stack:

    MyApp.exe!ZResult::ZResult(const ZResult & other) Line 26	C++
    MyApp.exe!QtMetaTypePrivate::QMetaTypeFunctionHelper<ZResult,1>::Construct(void * where, const void * t) Line 825	C++
    Qt5Cored.dll!QMetaType::construct(void * where, const void * copy) Line 2367	C++
    Qt5Qmld.dll!QV4::Heap::QQmlValueTypeWrapper::setValue(const QVariant & value) Line 116	C++
    Qt5Qmld.dll!QV4::QQmlValueTypeWrapper::create(QV4::ExecutionEngine * engine, const QVariant & value, const QMetaObject * metaObject, int typeId) Line 220	C++
    Qt5Qmld.dll!QV4::ExecutionEngine::fromVariant(const QVariant & variant) Line 1781	C++
    Qt5Qmld.dll!`anonymous namespace'::CallArgument::toValue(QV4::ExecutionEngine * engine) Line 1974	C++
    Qt5Qmld.dll!CallMethod(const QQmlObjectOrGadget & object, int index, int returnType, int argCount, int * argTypes, QV4::ExecutionEngine * engine, QV4::CallData * callArgs, QMetaObject::Call callType) Line 1303	C++
    Qt5Qmld.dll!CallPrecise(const QQmlObjectOrGadget & object, const QQmlPropertyData & data, QV4::ExecutionEngine * engine, QV4::CallData * callArgs, QMetaObject::Call callType) Line 1566	C++
    Qt5Qmld.dll!QV4::QObjectMethod::callInternal(const QV4::Value * thisObject, const QV4::Value * argv, int argc) Line 2128	C++
    Qt5Qmld.dll!QV4::QObjectMethod::virtualCall(const QV4::FunctionObject * m, const QV4::Value * thisObject, const QV4::Value * argv, int argc) Line 2066	C++
    Qt5Qmld.dll!QV4::FunctionObject::call(const QV4::Value * thisObject, const QV4::Value * argv, int argc) Line 203	C++
    Qt5Qmld.dll!QV4::Moth::VME::interpret(QV4::CppStackFrame * frame, QV4::ExecutionEngine * engine, const char * code) Line 754	C++
    Qt5Qmld.dll!QV4::Moth::VME::exec(QV4::CppStackFrame * frame, QV4::ExecutionEngine * engine) Line 463	C++
    Qt5Qmld.dll!QV4::Function::call(const QV4::Value * thisObject, const QV4::Value * argv, int argc, const QV4::ExecutionContext * context) Line 69	C++
    Qt5Qmld.dll!QQmlJavaScriptExpression::evaluate(QV4::CallData * callData, bool * isUndefined) Line 212	C++
    Qt5Qmld.dll!QQmlBoundSignalExpression::evaluate(void * * a) Line 226	C++
    Qt5Qmld.dll!QQmlBoundSignal_callback(QQmlNotifierEndpoint * e, void * * a) Line 362	C++
    Qt5Qmld.dll!QQmlNotifier::emitNotify(QQmlNotifierEndpoint * endpoint, void * * a) Line 105	C++
    Qt5Qmld.dll!QQmlData::signalEmitted(QAbstractDeclarativeData * __formal, QObject * object, int index, void * * a) Line 836	C++
    Qt5Cored.dll!doActivate<0>(QObject * sender, int signal_index, void * * argv) Line 3782	C++
    Qt5Cored.dll!QMetaObject::activate(QObject * sender, const QMetaObject * m, int local_signal_index, void * * argv) Line 3947	C++
    Qt5QuickTemplates2d.dll!QQuickAbstractButton::clicked() Line 631	C++
    Qt5QuickTemplates2d.dll!QQuickAbstractButtonPrivate::trigger() Line 343	C++
    Qt5QuickTemplates2d.dll!QQuickAbstractButtonPrivate::handleRelease(const QPointF & point) Line 183	C++
    Qt5QuickTemplates2d.dll!QQuickControl::mouseReleaseEvent(QMouseEvent * event) Line 2150	C++
    Qt5Quickd.dll!QQuickItem::event(QEvent * ev) Line 8166	C++
    Qt5QuickTemplates2d.dll!QQuickAbstractButton::event(QEvent * event) Line 1034	C++
    Qt5Cored.dll!QCoreApplicationPrivate::notify_helper(QObject * receiver, QEvent * event) Line 1222	C++
    Qt5Cored.dll!doNotify(QObject * receiver, QEvent * event) Line 1151	C++
    Qt5Cored.dll!QCoreApplication::notify(QObject * receiver, QEvent * event) Line 1138	C++
    Qt5Guid.dll!QGuiApplication::notify(QObject * object, QEvent * event) Line 1880	C++
    Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1061	C++
    Qt5Cored.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 1457	C++
    Qt5Quickd.dll!QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent * pointerEvent) Line 1901	C++
    Qt5Quickd.dll!QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent * event) Line 2490	C++
    Qt5Quickd.dll!QQuickWindowPrivate::handleMouseEvent(QMouseEvent * event) Line 2308	C++
    Qt5Quickd.dll!QQuickWindow::mouseReleaseEvent(QMouseEvent * event) Line 2288	C++
    Qt5Guid.dll!QWindow::event(QEvent * ev) Line 2337	C++
    Qt5Quickd.dll!QQuickWindow::event(QEvent * e) Line 1783	C++
    Qt5Cored.dll!QCoreApplicationPrivate::notify_helper(QObject * receiver, QEvent * event) Line 1222	C++
    Qt5Cored.dll!doNotify(QObject * receiver, QEvent * event) Line 1151	C++
    Qt5Cored.dll!QCoreApplication::notify(QObject * receiver, QEvent * event) Line 1138	C++
    Qt5Guid.dll!QGuiApplication::notify(QObject * object, QEvent * event) Line 1880	C++
    Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1061	C++
    Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1469	C++
    Qt5Guid.dll!QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent * e) Line 2215	C++
    Qt5Guid.dll!QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent * e) Line 1947	C++
    Qt5Guid.dll!QWindowSystemInterface::sendWindowSystemEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 1181	C++
    qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 82	C++
    Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 527	C++
    qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 73	C++
    Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 140	C++
    Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 232	C++
    Qt5Cored.dll!QCoreApplication::exec() Line 1369	C++
    Qt5Guid.dll!QGuiApplication::exec() Line 1868	C++
    MyApp.exe!main(int argc, char * * argv) Line 112	C++
    MyApp.exe!invoke_main() Line 79	C++
    MyApp.exe!__scrt_common_main_seh() Line 288	C++
    MyApp.exe!__scrt_common_main() Line 331	C++
    MyApp.exe!mainCRTStartup() Line 17	C++
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Why should it be moved ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      D 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Why should it be moved ?

        D Offline
        D Offline
        Dmitriano
        wrote on last edited by Dmitriano
        #3

        @SGaist Probably it is not quite correct question. I would not say 'it should', but theoretically it can be moved because it is returned as a temporary value from my findPeaks() function.

        kshegunovK 1 Reply Last reply
        0
        • D Dmitriano

          @SGaist Probably it is not quite correct question. I would not say 'it should', but theoretically it can be moved because it is returned as a temporary value from my findPeaks() function.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @Dmitriano said in Why Q_GADGET is not moved?:

          @SGaist Probably it is not quite correct question. I would not say 'it should', but theoretically it can be moved because it is returned as a temporary value from my findPeaks() function.

          This:

          var result = market.findPeaks()
          

          isn't c++, so copy elision (like the requested RVO) does not apply, nor is it applicable at all.

          Read and abide by the Qt Code of Conduct

          D 1 Reply Last reply
          5
          • kshegunovK kshegunov

            @Dmitriano said in Why Q_GADGET is not moved?:

            @SGaist Probably it is not quite correct question. I would not say 'it should', but theoretically it can be moved because it is returned as a temporary value from my findPeaks() function.

            This:

            var result = market.findPeaks()
            

            isn't c++, so copy elision (like the requested RVO) does not apply, nor is it applicable at all.

            D Offline
            D Offline
            Dmitriano
            wrote on last edited by Dmitriano
            #5

            @kshegunov Sure, 'copy elision' is not applicable, but I asked about 'std::move' (note that it is not the same). Theoretically QT engine can determine that the only reference to the gadget exists in QML and call move constructor. At least it is not obvious why this is not possible.

            kshegunovK 1 Reply Last reply
            0
            • D Dmitriano

              @kshegunov Sure, 'copy elision' is not applicable, but I asked about 'std::move' (note that it is not the same). Theoretically QT engine can determine that the only reference to the gadget exists in QML and call move constructor. At least it is not obvious why this is not possible.

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by kshegunov
              #6

              @Dmitriano said in Why Q_GADGET is not moved?:

              Sure, 'copy elision' is not applicable, but I asked about 'std::move' (note that it is not the same).

              Move semantics is there to facilitate copy elision, nothing else.

              Theoretically QT engine can determine that the only reference to the gadget exists in QML and call move constructor. At least it is not obvious why this is not possible.

              No it can't and yes, at least for me the reasoning is rather evident. C++ is a compiled language and is subject to static analysis and subsequent (asm) code generation + optimization. QML is neither of these things. How should or even could a dynamic language be "compiled in" asm, when the latter is already compiled into a target binary? (and that's of course assuming that the whole set of tools for such a thing are available in-language, which they aren't)
              Basically you're asking "why isn't c++ code recompiling itself while running".

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved