c++visual-studio-2013linker-errorsname-manglingcpputest

What causes difference in mangled names when compiling on the same compiler (vc12)?


I am currently trying to compile and link the CppUTest library with my project. I use CMake to create a Visual Studio 2013 Solution for the CppUTest-library and it builds.

However, when I link the created CppUTest.lib to my application I get an linker error telling me that it can not find multiple symbols like

??0Utest@@QAE@XZ)

or

?RunAllTests@CommandLineTestRunner@@SAHHPAPAD@Z

Now when I use dumpbin.exe on the lib and option /LINKERMEMBER I get a list of symbols in the library that includes the names

??0Utest@@QEAA@XZ

and

?RunAllTests@CommandLineTestRunner@@SAHHPEAPEAD@Z

So the names that actually exist are slightly different to the names that my projects expects and I have no idea what causes this problem. Is there any compile option that causes these changes or do I use a different compiler although I think it is the same?


Solution

  • Run the undname.exe utility from the Visual Studio Command Prompt. You get:

    Undecoration of :- "??0Utest@@QAE@XZ"
    is :- "public: __thiscall Utest::Utest(void)"
    

    and

    Undecoration of :- "??0Utest@@QEAA@XZ"
    is :- "public: __cdecl Utest::Utest(void) __ptr64"
    

    Clear enough that this is the default constructor of the Utest class. Note how the calling convention is different, __thiscall vs __cdecl. And how the library version has the __ptr64 attribute.

    You see that attribute appear on 64-bit functions. x64 has only one calling convention and does not distinguish between __cdecl and __thiscall.

    So it should start to get obvious, the linker wants the first one, the 32-bit version of the constructor. The 64-bit version you supplied can never work since you cannot mix 32-bit and 64-bit code. There should also be a loud warning about that, don't ignore such warnings.

    Link to the 32-bit build of this library to fix your problem. Or build the x64 version of your program.