C++ Undefined reference to defined constant

2.2k Views Asked by At

I've read through a number of questions on StackOverflow about undefined references but none seem to be specifically about an undefined reference to a constant that is defined in an included header. Apologies if I've missed a valid answer somewhere.

I am indirectly using MinGW 32bit (4.9.2) to compile C++ within Qt (5.5).

One of the included files defines a constant with #define but when the project is built the compiler complains of an undefined reference within the .cpp.

Weirdly I've tried testing if the constant exists on the line above its use and this has no problem.

Here's the compiler output:

g++ -Wl,-subsystem,windows -mthreads -o debug\THEPROJECT.exe object_script.THEPROJECT.Debug  -lmingw32 -LC:/Qt/5.5/mingw492_32/lib -lqtmaind -lshell32 -lole32 -lQt5Quickd -lQt5Guid -lQt5Qmld -lQt5Networkd -lQt5Cored 
./debug\RtAudio.o: In function `ZN11RtApiWasapi13getDeviceInfoEj':
C:\Users\ME\Documents\Code\build-THEPROJECT-Desktop_Qt_5_5_1_MinGW_32bit-Debug/../THEPROJECT/thirdparty/RtAudio.cpp:4128: undefined reference to `KSDATAFORMAT_SUBTYPE_IEEE_FLOAT'

Earlier within the .cpp, there's

#include <audioclient.h>

which in turn has

#include <mmreg.h>
#include <ks.h>
#include <ksmedia.h>

Within mmreg.h the constant is defined

#define DEFINE_GUIDEX(name) EXTERN_C const CDECL GUID name
#define DEFINE_GUIDSTRUCT(g,n) DEFINE_GUIDEX(n)
#define DEFINE_GUIDNAMED(n) n
...
#define STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_IEEE_FLOAT)
DEFINE_GUIDSTRUCT("00000003-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
#define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT #define DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)

Maybe it's worth noting that within ksmedia.h it is also defined. By putting (and later removing) #error directives I can tell that this definition gets run, though it strangely doesn't throw a 'redefined' warning. i.e. there doesn't appear to be an #ifndef bypassing it.

#define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)

Within the .cpp file the constant is used

  if ( deviceFormat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
       ( deviceFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
         ( ( WAVEFORMATEXTENSIBLE* ) deviceFormat )->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT ) )

On the line above this I have tested the constant by putting

#define __STR2__(x) #x
#define __STR1__(x) __STR2__(x)
#pragma message __STR1__(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)

and this successfully outputs #pragma message: KSDATAFORMAT_SUBTYPE_IEEE_FLOAT right before failing. Here's the compiler fragment

g++ -c -pipe -fno-keep-inline-dllexport -g -std=c++0x -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -D__WINDOWS_WASAPI__ -DQT_QML_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I..\THEPROJECT -I. -I..\THEPROJECT\thirdparty -I..\THEPROJECT\thirdparty\maximilian -IC:\Qt\5.5\mingw492_32\include -IC:\Qt\5.5\mingw492_32\include\QtQuick -IC:\Qt\5.5\mingw492_32\include\QtGui -IC:\Qt\5.5\mingw492_32\include\QtANGLE -IC:\Qt\5.5\mingw492_32\include\QtQml -IC:\Qt\5.5\mingw492_32\include\QtNetwork -IC:\Qt\5.5\mingw492_32\include\QtCore -Idebug -IC:\Qt\5.5\mingw492_32\mkspecs\win32-g++  -o debug\RtAudio.o ..\THEPROJECT\thirdparty\RtAudio.cpp
..\THEPROJECT\thirdparty\RtAudio.cpp: In member function 'virtual RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo(unsigned int)':
..\THEPROJECT\thirdparty\RtAudio.cpp:4122:57: note: #pragma message: KSDATAFORMAT_SUBTYPE_IEEE_FLOAT

This is probably a really stupid mistake but I've been headbanging for 2 days now. Any clues please?

EDIT: I've included a fuller reference to what's in mmreg.h

1

There are 1 best solutions below

0
On BEST ANSWER

It turns out that the issue was missing libraries in the compile statement. These libraries appear to be implicit when compiling with Microsoft Visual Studio but need to be linked explicitly when compiling with MinGW.

By adding -lwinmm -lksuser -luuid the problem was solved.

When compiling RtAudio for WASAPI control under Windows, these libraries are listed on the RtAudio page about compiling, so it was a silly error on my part not to have included them.

As a sidenote, the compiler error appears to be upon compiling RtAudio.cpp into RtAudio.o rather than at the linking stage, so I'm surprised that this apparent linking error showed up at that stage.

Thanks to everyone who contributed comments or answers.