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.7k 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.
  • Christian EhrlicherC Offline
    Christian EhrlicherC Offline
    Christian Ehrlicher
    Lifetime Qt Champion
    wrote on last edited by
    #2

    You must not reimplement a signal because it's done by moc but you did - either don't declare NewMessage() as signal or don't add an implementation for it.

    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
    Visit the Qt Academy at https://academy.qt.io/catalog

    A 1 Reply Last reply
    2
    • Christian EhrlicherC Christian Ehrlicher

      You must not reimplement a signal because it's done by moc but you did - either don't declare NewMessage() as signal or don't add an implementation for it.

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

      @Christian-Ehrlicher Thanks, I just found that. It is a SIGNAL and not a function...

      So I got it running but still no SLOT

      Am I doing the "emit" correctly ?

      connect(this,SIGNAL(NewMessage(QString text)),
                           this,SLOT(PostMessage(QString text)));
      

      // emit newMessage();

      QString TESTtext = "TEST MESSAGE ";

          emit NewMessage(TESTtext);
      
      JoeCFDJ Chris KawaC 2 Replies Last reply
      0
      • A Anonymous_Banned275

        @Christian-Ehrlicher Thanks, I just found that. It is a SIGNAL and not a function...

        So I got it running but still no SLOT

        Am I doing the "emit" correctly ?

        connect(this,SIGNAL(NewMessage(QString text)),
                             this,SLOT(PostMessage(QString text)));
        

        // emit newMessage();

        QString TESTtext = "TEST MESSAGE ";

            emit NewMessage(TESTtext);
        
        JoeCFDJ Offline
        JoeCFDJ Offline
        JoeCFD
        wrote on last edited by JoeCFD
        #4

        @AnneRanch
        signals:
        void NewMessage( const QString &msg);
        private slots:
        void PostMessage(const QString &msg );

        connect(this,SIGNAL(NewMessage(const QString &)),
        this,SLOT(PostMessage(const QString &)));

        1 Reply Last reply
        1
        • A Anonymous_Banned275

          @Christian-Ehrlicher Thanks, I just found that. It is a SIGNAL and not a function...

          So I got it running but still no SLOT

          Am I doing the "emit" correctly ?

          connect(this,SIGNAL(NewMessage(QString text)),
                               this,SLOT(PostMessage(QString text)));
          

          // emit newMessage();

          QString TESTtext = "TEST MESSAGE ";

              emit NewMessage(TESTtext);
          
          Chris KawaC Online
          Chris KawaC Online
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by Chris Kawa
          #5

          @AnneRanch said:

          Am I doing the "emit" correctly ?

          No, you shouldn't pass argument names to these macros. Also these functions don't have any parameters in your first post, so there shouldn't be any in the connect. If you want to pass a string there you need to change function signatures too.

          I know you said you don't want comments on the new syntax, but you really really really REALLY should use it. No, it's not a "lambda syntax". You don't have to use lambdas with it. It's just easier, safer, faster, has compile time errors and really should be your default. The old macro syntax is just legacy code at this point. You shouldn't be using it.

          Modern syntax (you don't need to know anything about the parameters):

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

          Old syntax (assuming you added parameters in these functions):

          connect(this, SIGNAL(NewMessage(const QString &)), this, SLOT(PostMessage(const QString &)));
          
          1 Reply Last reply
          1
          • Axel SpoerlA Offline
            Axel SpoerlA Offline
            Axel Spoerl
            Moderators
            wrote on last edited by
            #6

            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.

            Software Engineer
            The Qt Company, Oslo

            A S 2 Replies Last reply
            0
            • 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.

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

              @Axel-Spoerl Thanks , did not know connect return bool.
              All solved , thanks everybody.

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

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

                @Axel-Spoerl Thanks , did not know connect return bool.

                Well, the return type is actually QMetaObject::Connection, serving a boolean purpose in Q_ASSUME(). But I am sure you already knew, because you have rtfQm ;-)

                Software Engineer
                The Qt Company, Oslo

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

                  I need to reopen this.

                  I am happy to post / connect local SIGNAL to local SLOT. but I cannot get to post to "remote" class.
                  In my case BT_SPP_CA_MainWindow.

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

                  but I am getting this s error and I do not understand what "value" is it asking for.

                  /mnt/07b7c3f8-0efb-45ab-8df8-2a468771de1f/PROJECTS/BT_JAN11_ V1/CCC_SOURCE/BLUETOOTH_LIBRARY/chatserver_BT_copy.cpp:35: error: 'BT_SPP_CA_MainWindow' does not refer to a value
                  chatserver_BT_copy.cpp:35:49: error: 'BT_SPP_CA_MainWindow' does not refer to a value
                  connect(this,&BT_ChatServer::NewMessage,BT_SPP_CA_MainWindow,&BT_SPP_CA_MainWindow::PostMessage);
                  ^
                  ./../BT_SPP_CA/bt_spp_ca_mainwindow.h:32:7: note: declared here
                  class BT_SPP_CA_MainWindow : public QMainWindow
                  ^

                  Chris KawaC 1 Reply Last reply
                  0
                  • A Anonymous_Banned275

                    I need to reopen this.

                    I am happy to post / connect local SIGNAL to local SLOT. but I cannot get to post to "remote" class.
                    In my case BT_SPP_CA_MainWindow.

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

                    but I am getting this s error and I do not understand what "value" is it asking for.

                    /mnt/07b7c3f8-0efb-45ab-8df8-2a468771de1f/PROJECTS/BT_JAN11_ V1/CCC_SOURCE/BLUETOOTH_LIBRARY/chatserver_BT_copy.cpp:35: error: 'BT_SPP_CA_MainWindow' does not refer to a value
                    chatserver_BT_copy.cpp:35:49: error: 'BT_SPP_CA_MainWindow' does not refer to a value
                    connect(this,&BT_ChatServer::NewMessage,BT_SPP_CA_MainWindow,&BT_SPP_CA_MainWindow::PostMessage);
                    ^
                    ./../BT_SPP_CA/bt_spp_ca_mainwindow.h:32:7: note: declared here
                    class BT_SPP_CA_MainWindow : public QMainWindow
                    ^

                    Chris KawaC Online
                    Chris KawaC Online
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #10

                    @AnneRanch said:

                    but I cannot get to post to "remote" class.
                    connect(this,&BT_ChatServer::NewMessage,BT_SPP_CA_MainWindow,&BT_SPP_CA_MainWindow::PostMessage);

                    Connections are made between instances, not between classes. First and third parameters of connect should be pointers to source and destination instances. this is a pointer to instance of the class you're calling that code from. You've given a class name as the third parameter. You need to provide a pointer to the instance of that class instead.

                    A 1 Reply Last reply
                    2
                    • Chris KawaC Chris Kawa

                      @AnneRanch said:

                      but I cannot get to post to "remote" class.
                      connect(this,&BT_ChatServer::NewMessage,BT_SPP_CA_MainWindow,&BT_SPP_CA_MainWindow::PostMessage);

                      Connections are made between instances, not between classes. First and third parameters of connect should be pointers to source and destination instances. this is a pointer to instance of the class you're calling that code from. You've given a class name as the third parameter. You need to provide a pointer to the instance of that class instead.

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

                      @Chris-Kawa So I am reading it wrong , again

                      this (pointer) - source - is referring to a class which generates the SIGNAL

                      such class is called from the "parent" class which contains the desired destination SLOT

                      so I already have an instance of the destination and the source is in it.

                      If I create another class instance (pointer for the "destination class " - that is NOT where I want to send the message to.

                      I am actually looking n at this as a "parent / child" setting - I want to send a message generated by the child "up stream " to the parent..

                      Chris KawaC 1 Reply Last reply
                      0
                      • A Anonymous_Banned275

                        @Chris-Kawa So I am reading it wrong , again

                        this (pointer) - source - is referring to a class which generates the SIGNAL

                        such class is called from the "parent" class which contains the desired destination SLOT

                        so I already have an instance of the destination and the source is in it.

                        If I create another class instance (pointer for the "destination class " - that is NOT where I want to send the message to.

                        I am actually looking n at this as a "parent / child" setting - I want to send a message generated by the child "up stream " to the parent..

                        Chris KawaC Online
                        Chris KawaC Online
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by Chris Kawa
                        #12

                        this (pointer) - source - is referring to a class which generates the SIGNAL

                        No, not class. An instance of a class. An instance generates a signal. Class is just a type.

                        such class is called from the "parent" class which contains the desired destination SLOT

                        Classes are types. Types are not called. You can call o slot of an instance of a class.

                        If I create another class instance (pointer for the "destination class " - that is NOT where I want to send the message to.

                        Correct. Don't make a new instance. Get a pointer to the exact instance you want to send the signal to.

                        I am actually looking n at this as a "parent / child" setting

                        In general it doesn't have anything to do with parents/children. Connections are between instances of some classes. Those classes or instances don't have to be related in any way. The fact that in your case one of them is parent of the other is just anecdotal. It doesn't have special meaning for the connection.

                        I want to send a message generated by the child "up stream " to the parent

                        Although you technically can do that it's a bad design. Your operations should always be downstream, not up. Children are not supposed to know anything about their parents. This creates problems like yours - how do I get a pointer to parent. The answer is you shouldn't. It's the parent that should connect to its child's signal, because that's where you have the right context - pointers to both parent and child. When you're in the child's code you don't have easy access to the pointer to parent. Yes, you can call stuff like parentWidget() on this to get the parent and cast it to the right type, but that's ugly and hacky. The child gains knowledge about parent which it shouldn't have and you'll get into circular include problems fast.

                        I'd say move your connection to the parent class. this wil point to your parent class instance and you'll have a pointer to the child there, so you can do a connection like

                        connect(pointer_to_the_child, &BT_ChatServer::NewMessage, this, &BT_SPP_CA_MainWindow::PostMessage);
                        
                        A 1 Reply Last reply
                        1
                        • Chris KawaC Chris Kawa

                          this (pointer) - source - is referring to a class which generates the SIGNAL

                          No, not class. An instance of a class. An instance generates a signal. Class is just a type.

                          such class is called from the "parent" class which contains the desired destination SLOT

                          Classes are types. Types are not called. You can call o slot of an instance of a class.

                          If I create another class instance (pointer for the "destination class " - that is NOT where I want to send the message to.

                          Correct. Don't make a new instance. Get a pointer to the exact instance you want to send the signal to.

                          I am actually looking n at this as a "parent / child" setting

                          In general it doesn't have anything to do with parents/children. Connections are between instances of some classes. Those classes or instances don't have to be related in any way. The fact that in your case one of them is parent of the other is just anecdotal. It doesn't have special meaning for the connection.

                          I want to send a message generated by the child "up stream " to the parent

                          Although you technically can do that it's a bad design. Your operations should always be downstream, not up. Children are not supposed to know anything about their parents. This creates problems like yours - how do I get a pointer to parent. The answer is you shouldn't. It's the parent that should connect to its child's signal, because that's where you have the right context - pointers to both parent and child. When you're in the child's code you don't have easy access to the pointer to parent. Yes, you can call stuff like parentWidget() on this to get the parent and cast it to the right type, but that's ugly and hacky. The child gains knowledge about parent which it shouldn't have and you'll get into circular include problems fast.

                          I'd say move your connection to the parent class. this wil point to your parent class instance and you'll have a pointer to the child there, so you can do a connection like

                          connect(pointer_to_the_child, &BT_ChatServer::NewMessage, this, &BT_SPP_CA_MainWindow::PostMessage);
                          
                          A Offline
                          A Offline
                          Anonymous_Banned275
                          wrote on last edited by
                          #13

                          @Chris-Kawa So I moved the "connect" to "parent" .... Left the emit and the old test "connect" within "child".
                          The old test stuff still "passes the test message within child", the new connect does not.

                          I am not sure if the "emit" which is in the child get "pickled up" by the "connect" in the "parent"...

                          I do agree with your comments about the software should be "from top down" , however the hardware runs just the opposite - from child to parent ....from down to up

                          I actually tried to use inheritance and got stuck with same issue - how to pass messages upstream.

                          However, after last few days I feel more confident I could try inheritance again.....

                          I am going to take few days off - saying final goodbye to old friend ... not sure if we are going to fly or drive west from Houston...

                          cheers

                          Chris KawaC 1 Reply Last reply
                          0
                          • A Anonymous_Banned275

                            @Chris-Kawa So I moved the "connect" to "parent" .... Left the emit and the old test "connect" within "child".
                            The old test stuff still "passes the test message within child", the new connect does not.

                            I am not sure if the "emit" which is in the child get "pickled up" by the "connect" in the "parent"...

                            I do agree with your comments about the software should be "from top down" , however the hardware runs just the opposite - from child to parent ....from down to up

                            I actually tried to use inheritance and got stuck with same issue - how to pass messages upstream.

                            However, after last few days I feel more confident I could try inheritance again.....

                            I am going to take few days off - saying final goodbye to old friend ... not sure if we are going to fly or drive west from Houston...

                            cheers

                            Chris KawaC Online
                            Chris KawaC Online
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on last edited by Chris Kawa
                            #14

                            @AnneRanch said:

                            So I moved the "connect" to "parent" .... Left the emit and the old test "connect" within "child".

                            emit should be in the object that signals the change, so yes, it should stay in the child, as that is where the change takes place.
                            connect should be either where the slot is or somewhere outside entirely. For a parent/child connection it should be in the parent. For a connect of this to this it should be in that class, not in the parent, so what you did sounds right.

                            The old test stuff still "passes the test message within child", the new connect does not.

                            The type of connect doesn't matter. If it stopped working you just made something wrong.

                            however the hardware runs just the opposite - from child to parent

                            No, it doesn't. Hardware just does stuff. Child monitors the hardware and signals change in state. Parent picks up the signal and does something as a reaction. The information does flow upwards but the object structure is top to bottom.

                            I actually tried to use inheritance and got stuck with same issue - how to pass messages upstream.

                            It really doesn't sound like a job for inheritance. Inheritance represents "is" relation between classes. A dog is an animal. A car is a vehicle. Those are examples suited for inheritance. A dog has a collar. A car has a steering wheel. The "has" relation should be expressed as composition, not inheritance i.e. a parent has a child. In your case there is a MainWindow that has a ChatServer. That sounds like composition. MainWindow should not be a chat server.

                            A 1 Reply Last reply
                            1
                            • Chris KawaC Chris Kawa

                              @AnneRanch said:

                              So I moved the "connect" to "parent" .... Left the emit and the old test "connect" within "child".

                              emit should be in the object that signals the change, so yes, it should stay in the child, as that is where the change takes place.
                              connect should be either where the slot is or somewhere outside entirely. For a parent/child connection it should be in the parent. For a connect of this to this it should be in that class, not in the parent, so what you did sounds right.

                              The old test stuff still "passes the test message within child", the new connect does not.

                              The type of connect doesn't matter. If it stopped working you just made something wrong.

                              however the hardware runs just the opposite - from child to parent

                              No, it doesn't. Hardware just does stuff. Child monitors the hardware and signals change in state. Parent picks up the signal and does something as a reaction. The information does flow upwards but the object structure is top to bottom.

                              I actually tried to use inheritance and got stuck with same issue - how to pass messages upstream.

                              It really doesn't sound like a job for inheritance. Inheritance represents "is" relation between classes. A dog is an animal. A car is a vehicle. Those are examples suited for inheritance. A dog has a collar. A car has a steering wheel. The "has" relation should be expressed as composition, not inheritance i.e. a parent has a child. In your case there is a MainWindow that has a ChatServer. That sounds like composition. MainWindow should not be a chat server.

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

                              @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 1 Reply Last reply
                              0
                              • 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 Online
                                Chris KawaC Online
                                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 Online
                                    Chris KawaC Online
                                    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 Online
                                        JonBJ Online
                                        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

                                          • Login

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