New operator and some others don't have matching symbol names between clang and visual studio?


I have an issue while trying to link some clang compiled code. When I compile my test dll with clang I get a new operator like this:


I guess this is conformant with GCC’s naming.

But when compiling with visual studio the new operator is:

Searching libraries
Searching C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\LIB\MSVCRTD.lib:
Found __purecall
Referenced in ConsoleApplication2.obj
Loaded MSVCRTD.lib(MSVCR110D.dll)
Found “void * __cdecl operator new(unsigned int)” (??2@YAPAXI@Z)
Referenced in ConsoleApplication2.obj
Loaded MSVCRTD.lib(MSVCR110D.dll)
Found “void __cdecl operator delete(void *)” (??3@YAXPAX@Z)
Referenced in ConsoleApplication2.obj
Loaded MSVCRTD.lib(MSVCR110D.dll)

I also noticed that with Clang I get a symbol for pure call catches called:

I assume the __purecall above is the visual studio version.

When I try to link the clang compiled object file using link.exe I get unresolved symbol errors because of this.

F:\LLVM-fresh\vs11\bin\Debug>clang++ -c testdll.cpp -o testdll.o -v
clang version 3.5 (trunk)
Target: i686-pc-win32
Thread model: posix
“F:\LLVM-fresh\vs11\bin\Debug\clang++.exe” -cc1 -triple i686-pc-win32 -emit-obj
-mrelax-all -disable-free -main-file-name testdll.cpp -mrelocation-model static
-mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -target-cpu
pentium4 -v -coverage-file “F:\LLVM-fresh\vs11\bin\Debug\testdll.o” -resour
ce-dir “F:\LLVM-fresh\vs11\bin\Debug\…\lib\clang\3.5” -internal-isystem
“F:\LLVM-fresh\vs11\bin\Debug\…\lib\clang\3.5\include” -internal-isys
tem “C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE” -intern
al-isystem “C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ATLMFC\I
NCLUDE” -internal-isystem “C:\Program Files (x86)\Microsoft SDKs\Windows\v7.
0A\include” -std=c++11 -fdeprecated-macro -fdebug-compilation-dir “F:\LLVM-fre
sh\vs11\bin\Debug” -ferror-limit 19 -fmessage-length 80 -mstackrealign -fms-e
xtensions -fms-compatibility -fmsc-version=1700 -fdelayed-template-parsing -fobj
c-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-di
agnostics -vectorize-slp -o testdll.o -x c++ testdll.cpp
clang -cc1 version 3.5 based upon LLVM 3.5svn default target i686-pc-win32
#include “…” search starts here:
#include <…> search starts here:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ATLMFC\INCLUDE
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include
End of search list.

F:\LLVM-fresh\vs11\bin\Debug>nm testdll.o
00000000 t .text
00000000 t .text
00000001 a @feat.00
00000000 T __ZN7testOneC2Ev
U __Znwj
00000000 T _whatever


C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin>link /DLL /NOENTRY te
stdll.o /VERBOSE
Microsoft (R) Incremental Linker Version 11.00.50727.1
Copyright (C) Microsoft Corporation. All rights reserved.

Starting pass 1

Searching libraries

Finished searching libraries

Finished pass 1

testdll.o : error LNK2019: unresolved external symbol __Znwj referenced in funct
ion _whatever
testdll.dll : fatal error LNK1120: 1 unresolved externals

How can I get this to link? Thanks.

clang++.exe defaults to the mingw ABI. It seems you want to use clang-cl.exe, it uses the MSVC ABI. Note that clang-cl.exe’s argument parsing is compatible with MSVC’s cl.exe while clang++.exe is compatible with gcc.

Hey David,

Thanks a lot for the quick response. I had assumed this mode was already enabled since while using clang++.exe it said the target is i686-pc-win32 rather than i686-pc-mingw. When calling the clang driver cc1 directly is “-cxx-abi” “microsoft” the argument that enables this mode? Thanks.

You are correct that “-cxx-abi microsoft” with an appropriate win32 triple is what I would consider ABI compatible. However, reliance on that cc1 flag is ill-advised. I (and to my knowledge all others involved in the MSVC ABI effort) want the triple to implicitly control which ABI is selected while removing the -cxx-abi flag altogether.

Makes sense to me. I think most people picking up clang for the first time would assume that to be the default behavior. Thanks a lot for the help.