Undefined Reference Linker Error
-
I am getting the Undefined Reference Error in the linker step to my now sizeable project. Windows 11, Qt Ver 6.6.2 MinGW 64, Qt Creator ver 15.0.0-
I just added two new classes derived from QChart: Realtimeplot0 and MultSersPlot.
Here is the relevant items for Realtimeplot0:#include <QChart> #include "Macros.h" #include <boost/circular_buffer.hpp> class QGestureEvent; class TDADataMap; class QLineSeries; class Realtimeplot0 : public QChart { private: Q_OBJECT public: explicit Realtimeplot0(QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = {}); ...... (Lots of other declarations...) QColor &GetSeriesColor(int cc); ...... (Lots of protected and private stuff...) };
In the .cpp file:
static QList<QColor> __rtpColors; // Defined in the Constructor: __rtpColors << Qt::blue << Qt::red << Qt::yellow << Qt::green << Qt::magenta << Qt::black << Qt::darkGray; QColor &GetSeriesColor(int cc) { static QColor __rtrnClr = __rtpColors[0]; int ndx = cc % __rtpColors.size(); __rtrnClr = __rtpColors[ndx]; return __rtrnClr; }
Here is header to MuiltsersPlot:
class MultSersPlot : public Realtimeplot0 { private: Q_OBJECT public: MultSersPlot(QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = {}); void FinishPlot(TDADataMap *) override; void setAxisRange(QPointF minrng, QPointF maxrng, bool frc = false) override; void SetYVarData(int srsnr, int vnr); };
And the Source file that generates the error (the only place currently where GetSeriesColor is invoked:
void MultSersPlot::SetYVarData(int srsnr, int vnr) { QString srsName = QString("RealTime%1").arg(srsnr); switch (srsnr) { case 1: SetYVar1(vnr); break; case 2: SetYVar2(vnr); break; case 3: SetYVar3(vnr); break; case 4: SetYVar4(vnr); break; default: return; } if (m_data.size() < srsnr) { m_data.append(QList<QPointF>()); } else { m_data[srsnr - 1].clear(); } if (m_buffData.size() < srsnr) { m_buffData.append(boost::circular_buffer<QPointF>(GetBuffSz())); } else m_buffData[srsnr - 1].clear(); if (m_plotSeries.size() < srsnr) { QLineSeries *realtimeseries = new QLineSeries; realtimeseries->setName(srsName); QColor srsClr = GetSeriesColor(srsnr); QPen srsPen; srsPen.setWidth(2); srsPen.setColor(srsClr); realtimeseries->setPen(srsPen); realtimeseries->setPointsVisible(true); QList<QAbstractAxis *> axs; axs = axes(Qt::Vertical, m_plotSeries[0]); realtimeseries->attachAxis(axs[0]); axs = axes(Qt::Horizontal, m_plotSeries[0]); realtimeseries->attachAxis(axs[0]); m_plotSeries.append(realtimeseries); } }
The compile output (though I think the last are linker errors)
D:\kcbdev\bips_svn\CommonWidgets\CalEditFormBase.ui:-1: Warning: The name 'horizontalLayout' (QHBoxLayout) is already in use, defaulting to 'horizontalLayout1'. D:\kcbdev\bips_svn\CommonWidgets\CalEditFormBase.ui:-1: Warning: The name 'gridLayout_8' (QGridLayout) is already in use, defaulting to 'gridLayout_81'. D:\kcbdev\bips_svn\CommonWidgets\advProtocolDlgBase.ui:-1: Warning: The name 'gridLayout' (QGridLayout) is already in use, defaulting to 'gridLayout3'. D:\kcbdev\bips_svn\CommonWidgets\advProtocolDlgMGABase.ui:-1: Warning: The name 'gridLayout' (QGridLayout) is already in use, defaulting to 'gridLayout3'. D:\kcbdev\bips_svn\CommonWidgets\AWProtocolDlgBase.ui:-1: Warning: The name 'gridLayout' (QGridLayout) is already in use, defaulting to 'gridLayout1'. D:\kcbdev\bips_svn\BIPS10\BIPSMain\BIPSMain.cpp:5: '#pragma message: In BIPSMain: Qt Version: 6.6.2' D:/kcbdev/bips_svn/BIPS10/BIPSMain/BIPSMain.cpp:5:59: note: '#pragma message: In BIPSMain: Qt Version: 6.6.2' 5 | #pragma message("In BIPSMain: Qt Version: " QT_VERSION_STR) | ^ :-1: error: CMakeFiles/BIPSMain.dir/D_/kcbdev/bips_svn/CommonWidgets/MultSersPlot.cpp.obj:MultSersPlot.c:(.bss+0x0): multiple definition of `savvmx'; CMakeFiles/BIPSMain.dir/D_/kcbdev/bips_svn/CommonWidgets/FVCalPlot.cpp.obj:FVCalPlot.cpp:(.bss+0x0): first defined here :-1: error: CMakeFiles/BIPSMain.dir/D_/kcbdev/bips_svn/CommonWidgets/MultSersPlot.cpp.obj:MultSersPlot.c:(.bss+0x4): multiple definition of `savvmn'; CMakeFiles/BIPSMain.dir/D_/kcbdev/bips_svn/CommonWidgets/FVCalPlot.cpp.obj:FVCalPlot.cpp:(.bss+0x4): first defined here :-1: error: CMakeFiles/BIPSMain.dir/D_/kcbdev/bips_svn/CommonWidgets/MultSersPlot.cpp.obj:MultSersPlot.c:(.text+0xe66): undefined reference to `Realtimeplot0::GetSeriesColor(int)' :-1: error: collect2.exe: error: ld returned 1 exit status :-1: error: ninja: build stopped: subcommand failed.
I have tried all sorts of solutions, none worked:
I moved the RealtimePlot.h and .cpp files to the top of my CMakeLists.txt file
I deleted the build folders to force Qt to start the build from scratch
I have run several 'Rebuild' operations from the QtCreator menu.
None work, I always get this error. The program worked fine until I recently added this new GetSeriesColor method.
Any help? -
Hi,
You declared that function in your class but you implemented it without the class scope in your .cpp file.
-
@SGaist has addressed the last error message from your linker.
The two preceding error messages regarding
savvmx
andsavvmn
are probably because you have the storage for these allocated in a header file rather than a cpp file. Everywhere you include the header you get another instance of the same storage and symbol.The use of names starting with double-underscore are reserved for the compiler implementation and should not be present in user code. It may work with a given toolchain but I would expect compiler warnings and portability will be degraded.
See 7.1.3 in ISO/IEC 9899:201x (draft) -
-
Any descriptive name that is not explicitly reserved should be fair. So
defaultColors
or_defaultColors
would be OK;_DefaultColors
or__defaultColors
would not.File-scoped variables can be declared
static
and become invisible outside the translation unit. Standard advice is to question the need for such variables and use an anonymous namespace instead ofstatic
:namespace { QList<QColor> defaultColors { Qt::blue, Qt::red, Qt::yellow, Qt::green, Qt::magenta, Qt::black, Qt::darkGray }; }; // rest of file can see defaultColors
If your file-local color list is being populated in the constructor of a class then that strongly suggests it should be part of the class or initialised outside the class (as above).
__rtrnClr
in GetSeriesColor seems to have no need to exist.
Are you sure the function needs a non-const reference return value and not just a QColor?