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. ":connect' error - "multiple definition..." ?
Forum Updated to NodeBB v4.3 + New Features

":connect' error - "multiple definition..." ?

Scheduled Pinned Locked Moved Solved General and Desktop
25 Posts 7 Posters 3.2k Views 4 Watching
  • 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.
  • A Anonymous_Banned275

    @Chris-Kawa I am stuck....

    Here are my two test macros

        Q_ASSUME(connect(this, &BT_SPP_CA_MainWindow::NewMessage, this, &BT_SPP_CA_MainWindow::PostMessage));
        Q_ASSUME(connect(server,&BT_ChatServer::NewMessage,this,&BT_SPP_CA_MainWindow::PostMessage));
    

    The top one works when I "emit" NewMessage in BT_SPP_CA_MainWindow instance.

    The bottom one does not work - it seems to ignore the "emit New Meassage" in BT_ChatServer and I have several of them which works fine "locally" in BT_ChatServer .

    My "server" is initialized and processes other calls...including local emit NewMessage...

    What else can I do to identify / debug the issue ?

    Chris KawaC Offline
    Chris KawaC Offline
    Chris Kawa
    Lifetime Qt Champion
    wrote on last edited by
    #16

    @AnneRanch Are you sure you're connecting the right instances? You can print out the pointer and compare the addresses i.e. qDebug() << server; where you make that connection and qDebug() << this; inside BT_ChatServer where you say it works. It should be the same address printed out. If not then you mixed your instances somewhere.

    A 1 Reply Last reply
    0
    • Chris KawaC Chris Kawa

      @AnneRanch Are you sure you're connecting the right instances? You can print out the pointer and compare the addresses i.e. qDebug() << server; where you make that connection and qDebug() << this; inside BT_ChatServer where you say it works. It should be the same address printed out. If not then you mixed your instances somewhere.

      A Offline
      A Offline
      Anonymous_Banned275
      wrote on last edited by
      #17

      @Chris-Kawa Here is a snippet of app output
      The pointers match

      void BT_SPP_CA_MainWindow::Connect_MainServer()
      BT_ChatServer::BT_ChatServer(QObject *)
      "\n\t TASK Run \nBT_ChatServer::BT_ChatServer(QObject *)\n"
      !!!!!!!!!!!!!!!!!!! this BT_ChatServer(0x5653f9b74550)
      conncet OK
      TASK Construct BT_ChatServer
      BT_ChatServer::BT_ChatServer(QObject *)
      & line "84"
      !!!!!!!!!!!!!!!!!!!!server BT_ChatServer(0x5653f9b74550)
      !!!!!!!!!!!!!!!!!!! this BT_ChatServer(0x5653f9b74550)

      "emit NewMessage(text)"
      void BT_ChatServer::PostMessage(const QString)
      "\n\t TASK Run \nvoid BT_ChatServer::PostMessage(const QString)\n !!!! REMOTE !!!! TEST MESSAGE "

      Chris KawaC 1 Reply Last reply
      0
      • A Anonymous_Banned275

        @Chris-Kawa Here is a snippet of app output
        The pointers match

        void BT_SPP_CA_MainWindow::Connect_MainServer()
        BT_ChatServer::BT_ChatServer(QObject *)
        "\n\t TASK Run \nBT_ChatServer::BT_ChatServer(QObject *)\n"
        !!!!!!!!!!!!!!!!!!! this BT_ChatServer(0x5653f9b74550)
        conncet OK
        TASK Construct BT_ChatServer
        BT_ChatServer::BT_ChatServer(QObject *)
        & line "84"
        !!!!!!!!!!!!!!!!!!!!server BT_ChatServer(0x5653f9b74550)
        !!!!!!!!!!!!!!!!!!! this BT_ChatServer(0x5653f9b74550)

        "emit NewMessage(text)"
        void BT_ChatServer::PostMessage(const QString)
        "\n\t TASK Run \nvoid BT_ChatServer::PostMessage(const QString)\n !!!! REMOTE !!!! TEST MESSAGE "

        Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by
        #18

        @AnneRanch It's very difficult for me to decipher that stream of random text without the matching code, but you said earlier that you had this:

        Q_ASSUME(connect(server,&BT_ChatServer::NewMessage,this,&BT_SPP_CA_MainWindow::PostMessage));
        

        but the output says this:

        !!!!!!!!!!!!!!!!!!!!server BT_ChatServer(0x5653f9b74550)
        !!!!!!!!!!!!!!!!!!! this BT_ChatServer(0x5653f9b74550)
        

        so which is it, because it's physically impossible that this output matches that connect. this can't be both BT_SPP_CA_MainWindow and BT_ChatServer at the same time, so what's the real code that produces this output?.

        1 Reply Last reply
        1
        • Axel SpoerlA Axel Spoerl

          connect(this, &BT_ChatServer::NewMessage, this, &BT_ChatServer::PostMessage);

          connect() returns a boolean, so wrapping it with Q_ASSUME(connect(...))will tell right away, if the connection was successful.
          The syntax proposed by @Chris-Kawa is the recommended one.

          S Offline
          S Offline
          SimonSchroeder
          wrote on last edited by
          #19

          @Axel-Spoerl said in ":connect' error - "multiple definition..." ?:

          so wrapping it with Q_ASSUME(connect(...))will tell right away, if the connection was successful.

          Will it, though? I had to quickly look up Q_ASSUME. From my understanding it just tells the compiler that you assert that the return value of the connect is always true. The compiler is allowed to use this assumption for optimization. If the assumption is wrong you have undefined behavior. Or does it actually do a check? I have seen people suggest Q_ASSERT, but this will only do the connect in the debug build, not in the release build. Is there a macro you could actually use here? Or am I mistaken about Q_ASSUME?

          With the new connect syntax rarely if ever will the connect fail if it compiles. I have to admit that I never check the return value. Qt will write out warning to the console, though, when the connect fails. This is how you can figure this out at runtime as well.

          JonBJ 1 Reply Last reply
          1
          • S SimonSchroeder

            @Axel-Spoerl said in ":connect' error - "multiple definition..." ?:

            so wrapping it with Q_ASSUME(connect(...))will tell right away, if the connection was successful.

            Will it, though? I had to quickly look up Q_ASSUME. From my understanding it just tells the compiler that you assert that the return value of the connect is always true. The compiler is allowed to use this assumption for optimization. If the assumption is wrong you have undefined behavior. Or does it actually do a check? I have seen people suggest Q_ASSERT, but this will only do the connect in the debug build, not in the release build. Is there a macro you could actually use here? Or am I mistaken about Q_ASSUME?

            With the new connect syntax rarely if ever will the connect fail if it compiles. I have to admit that I never check the return value. Qt will write out warning to the console, though, when the connect fails. This is how you can figure this out at runtime as well.

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #20

            @SimonSchroeder said in ":connect' error - "multiple definition..." ?:

            If the assumption is wrong you have undefined behavior. Or does it actually do a check?

            I believe you are quite correct here. It does not do a check, unlike Q_ASSERT, rather it tells the compiler what is going to happen.

            The OP actually asked about this in Usage of Q_ASSUME in connect ?.

            1 Reply Last reply
            0
            • Axel SpoerlA Offline
              Axel SpoerlA Offline
              Axel Spoerl
              Moderators
              wrote on last edited by
              #21

              @SimonSchroeder said in ":connect' error - "multiple definition..." ?:

              Q_ASSUME?

              Maybe I wasn't clear in my proposal to wrap QObject::connect() into Q_ASSUME().
              This is for debugging and analyzing, if a connection was successful at all.
              It's not recommended for production code, however.
              Q_ASSUME() instructs the compiler to assume, that the wrapped condition is true. That's for optimizing purposes. The condition itself can be optimized out, even if that's not always the case. It remains the compiler's decision.
              Q_ASSERT() will always kick in debug builds and is completely optimized out on production. In a debug build, Q_ASSUME becomes a Q_ASSERT, so they are treated identically.

              Having said that, the safe way to assert a connection is to read it's return value into a variable, debug it and act on it. Connections should be designed such, that they always work. Once the plumbing is done, all the wrappers can go out. They create unnecessary overhead in stable code. That's why QObject::connect() is not marked nodiscard, like other functions that do not allow their return value to be ignored.

              Software Engineer
              The Qt Company, Oslo

              1 Reply Last reply
              1
              • A Offline
                A Offline
                Anonymous_Banned275
                wrote on last edited by
                #22

                I have added some"B@W" so we can see the compiler / linker actual output.
                It still shows that the pointers match.

                BT_ChatServer::BT_ChatServer(QObject *)
                & line "84"
                DEBUG connect void BT_SPP_CA_MainWindow::Connect_MainServer() @ line "1399" this BT_SPP_CA_MainWindow(0x558ce48df8f0, name="BT_SPP_CA_MainWindow")
                DEBUG connect void BT_SPP_CA_MainWindow::Connect_MainServer() @ line "1400" server BT_ChatServer(0x558ce4df7170)
                !!!!!!!!!!!!!!!!!!!!server BT_ChatServer(0x558ce4df7170)
                DEBUG connect void BT_ChatServer::startServer(const QBluetoothAddress &) @ line "109" this BT_ChatServer(0x558ce4df7170)

                "emit NewMessage(text)"
                void BT_ChatServer::PostMessage(const QString)

                As far as Q_ASSUME goes - it does check the syntax , not the actual function of the "connect" .
                This is helpful.

                I do understated there may be alternatives to accomplish passing messages between objects, but my goal is to find out WHY this does not work.
                ( The BT_ChatServer is a member of BT_SPP_CA_MainWindow )

                If I have a multiple and WRONG "connect" would it still do something , even if incorrect ?
                It is (remotely) possible that the "new" syntax does not works BETWEEN objects ?
                ( I just cannot believe this "passing messages", was never tried by some other coder ....)

                Let's keep in focus, it does not matter what / where the error is, I just want to resolve it,
                putting the blame on something / somebody IS NOT my goal.

                .

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  Anonymous_Banned275
                  wrote on last edited by
                  #23

                  Maybe Q_ASSUME will do more...

                  I went back to the "old style" too,
                  The old style complains about missing parameter.

                  Then my usage of Q_ASSUME is also wrong - I need to fix that and see if it will help to locate the problem...

                  ..and yes,, I hand two instances of "server" , but either one should pass the test message....

                  QObject::connect: No such signal BT_ChatServer::&BT_ChatServer().NewMessage() in bt_spp_ca_mainwindow.cpp:1466
                  QObject::connect:  (receiver name: 'BT_SPP_CA_MainWindow')
                  ASSERT failure in Q_ASSUME(): "Assumption in Q_ASSUME("connect (server,SIGNAL(&BT_ChatServer().NewMessage()), this,SLOT(&BT_SPP_CA_MainWindow().PostMessage()) );") was not correct", file bt_spp_ca_mainwindow.cpp, line 1470
                  11:16:58: /mnt/07b7c3f8-0efb-45ab-8df8-2a468771de1f/PROJECTS/BT_JAN13_/Qt-5.15.2/widgets/mainwindows/mdi/mdi crashed.
                  
                  
                              Q_ASSUME(
                                      connect
                                              (server,SIGNAL(&BT_ChatServer().NewMessage()),
                                               this,SLOT(&BT_SPP_CA_MainWindow().PostMessage())
                                               );
                  
                                      );
                  
                  
                             //Q_ASSUME(connect(this, &BT_SPP_CA_MainWindow::NewMessage, this, &BT_SPP_CA_MainWindow::PostMessage));
                  
                              Q_ASSUME(connect(server,&BT_ChatServer::NewMessage,this,&BT_SPP_CA_MainWindow::PostMessage));
                  
                              qDebug() <<"DEBUG connect " << Q_FUNC_INFO << "@ line " << QString::number(__LINE__) << " server  " << server;
                  
                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    Anonymous_Banned275
                    wrote on last edited by
                    #24

                    more debugging....
                    Added another class member , "standard" Qt Designer Form class with single TEST button emitting test message.

                    SUCCESS The message gets passed to the "parent" using "connect"....

                    What is puzzling - the debug outputs are in reverse sequence...

                    So - I must have a wrong "connect " somewhere.... in my original code....

                    1478edf2-5f82-4789-a5ef-ed8d5d34d267-image.png

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      Anonymous_Banned275
                      wrote on last edited by
                      #25

                      SOLVED

                      Eureka !!
                      The original QT example code has multiple instances of ChatServer and no "delete".

                      Now a minor curiosity question remains:
                      if the test code emits TWO messages , why do I get only ONE "postmessage " ?

                      void BT_ChatServer::PostMessage(const QString)
                      "\n\t TASK Run \nvoid BT_ChatServer::PostMessage(const QString)\n !!!! REMOTE !!!! TEST MESSAGE "
                      void BT_ChatServer::PostMessage(const QString)
                      "\n\t TASK Run \nvoid BT_ChatServer::PostMessage(const QString)\n !!!! REMOTE !!!! TEST MESSAGE "
                      void BT_SPP_CA_MainWindow::PostMessage(const QString)
                      "\n\t TASK Run \nvoid BT_SPP_CA_MainWindow::PostMessage(const QString)\n !!!! REMOTE !!!! TEST MESSAGE "

                      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