Signals being optimized out.
-
I have a plugin that contains some slots. The slots connect inside the plugin to signals in the base application. This works fine when compiling in debug mode, but when I try this in release mode I get the runtime message:
Warning: QObject::connect: signal not found in MyClass
I've narrowed this down to compiler optimization: If I set the release mode to use the -O0 flag in g++, everything works just fine (-O2 is the default for release mode).
I've tried applying the Q_DECL_EXPORT macro, but this doesn't seem to work...
Disabling compiler optimization works for now, but I'd like to use optimization in my releases. Is there a better way to prevent the compiler from optimizing signals out?
-
Hi,
First time I see this. Can you show your class declaration ?
And an example of use ?What OS are running ?
Which compiler are you using ? -
Try adding C++ just after the three backticks on the same line.
-
-
The class looks correct and there's nothing wrong with signal forwarding.
Can you reproduce that with a minimal code sample ?
By the way, which version of Qt are you using ?
-
A tiny idea I'd try if I were you:
I'd try making an-O2
build with debug symbols, like the ones used for profiling (breakpoints work okay, step-by-step not, unless you're following the actual assembly). It's pretty clumsy to debug with it, but better than guessing and relying on printed messages. -
@kshegunov said in Signals being optimized out.:
I'd try making an -O2 build with debug symbols
I just compiled it in debug with -O2. Confirmed the same problem exists, so optimization is %100 the culprit. When I break at the 'connect(' line, I can see the signal in the '[methods]' section of the object
but in the '[signals]' section of '[extra]', the signal index is there with the same parameter, but the name of the signal is listed as '<not accessible>'
This kind of makes me think that the signal function declaration is there just fine, but the MOC's signal definition is missing? I'm not %100 percent on how exactly the MOC works, but the debugger seems to be able to see the original function signature.
-
@kshegunov said in Signals being optimized out.:
I'd try making an -O2 build with debug symbols
I just compiled it in debug with -O2. Confirmed the same problem exists, so optimization is %100 the culprit. When I break at the 'connect(' line, I can see the signal in the '[methods]' section of the object
but in the '[signals]' section of '[extra]', the signal index is there with the same parameter, but the name of the signal is listed as '<not accessible>'
This kind of makes me think that the signal function declaration is there just fine, but the MOC's signal definition is missing? I'm not %100 percent on how exactly the MOC works, but the debugger seems to be able to see the original function signature.
@LScott said in Signals being optimized out.:
but in the '[signals]' section of '[extra]', the signal index is there with the same parameter, but the name of the signal is listed as '<not accessible>'
It may be a red herring, don't weigh it too important.
This kind of makes me think that the signal function declaration is there just fine, but the MOC's signal definition is missing?
Nope, because your code wouldn't compile in that case, you could check if you want but I assure you the definition is there. The source generated by
moc
from a headerheadername.h
ismoc_headername.cpp
, search for it in your build directory.I'm not %100 percent on how exactly the MOC works, but the debugger seems to be able to see the original function signature.
It writes a C++ file for you based on parsing the header and the special macros.
Could you attempt to break the emission into two parts:
- Catch the original slot in a lambda to see if the original signal's emitted.
- Emit the
QPort::RxRateChanged
manually, to make sure the forwarded signal is emitted.
Something along this:
QObject::connect(&_rxRate, &RateMeasurement::RateChanged, this, [this] (double arg) -> void { // Break here with the debugger emit RxRateChanged(arg); });
-
@kshegunov said in Signals being optimized out.:
Nope, because your code wouldn't compile in that case
I meant more along the line of the MOC function definition gets compiled in just fine, but optimized out.
I tried it with the anonymous function, but got same result, and the breakpoint is never hit. I get the same message about the signal not being found. I'm assuming the signal it's referring to is the source (RateMeasurement::RateChanged).
-
I found your problem,
you try to QObject::connect two normal functions together, this compiles but results in
QObject::connect: signal not found in MainWindow
error.take this minimal example class, it reproduces the error:
#include <QMainWindow> class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); void doNothing(); void doNothingElse(); };
#include "mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { connect(this, &MainWindow::doNothing, this, &MainWindow::doNothingElse); doNothing(); } void MainWindow::doNothing() { qDebug() << "doNothing"; } void MainWindow::doNothingElse() { qDebug() << "doNothingElse"; }
-
@J.Hilk said in Signals being optimized out.:
I found your problem,
you try to QObject::connect two normal functions together, this compiles but results in QObject::connect: signal not found in MainWindow error.I'm afraid this isn't the problem... I don't see anywhere where I'm connecting two normal functions? Both are signals, which is completely valid.
As stated, it compiles and runs fine with no compiler optimization, the issue only arises when compiler optimization is set to -O2.
-
Can you show your code ?
-
@SGaist said in Signals being optimized out.:
Can you show your code ?
I'm working on a minimal reproducible example, because the code in question is part of a much larger project.
In short:
Static Library:
class RateMeasurement : public QObject { Q_OBJECT public: RateMeasurement(QObject *parent = NULL) : QObject(parent) {} signals: Q_DECL_EXPORT void RateChanged(const double rate); } class QPort : public QObject { Q_OBJECT public: QPort(QObject *parent = NULL) : QObject(parent) { QObject::connect(&_txRate, &RateMeasurement::RateChanged, this, &QPort::TxRateChanged); QObject::connect(&_rxRate, &RateMeasurement::RateChanged, this, &QPort::RxRateChanged); } signals: void RxRateChanged(double rate); void TxRateChanged(double rate); protected: RateMeasurement _txRate; RateMeasurement _rxRate; }
I then have a plugin (dynamic library) that contains an object that extends from 'QPort'. When an instance of this derived class is constructed (in an application that loads the plugin), that's when I see the error. Works flawlessly in debug/non-optimized release mode.
-
Both are in the same library ?
-
@kshegunov said in Signals being optimized out.:
Nope, because your code wouldn't compile in that case
I meant more along the line of the MOC function definition gets compiled in just fine, but optimized out.
I tried it with the anonymous function, but got same result, and the breakpoint is never hit. I get the same message about the signal not being found. I'm assuming the signal it's referring to is the source (RateMeasurement::RateChanged).
@LScott said in Signals being optimized out.:
I tried it with the anonymous function, but got same result, and the breakpoint is never hit. I get the same message about the signal not being found. I'm assuming the signal it's referring to is the source (RateMeasurement::RateChanged).
This would be my guess as well. Something's fishy about this signal then. I'd then find the moc code and see what was generated for that class.
I then have a plugin (dynamic library) that contains an object that extends from 'QPort'. When an instance of this derived class is constructed (in an application that loads the plugin)
This sounds strange. How do you get a plugin class to derive from a class that's contained in static library? Do you link it twice (once in the application, once in the plugin) perhaps?