I have installed clang version 6.0 as well as Visual Studio 2017. I am compiling a simple 'hello world' application:
#include <iostream>
int main()
{
std::cout << "Hello, World!" << std::endl;
return 0;
}
using
clang hello.cpp
This gives me warnings:
hello-d1b2c6.o : warning LNK4217: locally defined symbol __std_terminate
imported in function "int `public: static unsigned __int64 __cdecl
std::char_traits<char>::length(char const * const)'::`1'::dtor$2"
(?dtor$2@?0??length@?$char_traits@D@std@@SA_KQEBD@Z@4HA)
hello-d1b2c6.o : warning LNK4217: locally defined symbol _CxxThrowException
imported in function "public: void __cdecl std::ios_base::clear(int,bool)"
(?clear@ios_base@std@@QEAAXH_N@Z)
I am aware that I can mitigate these warnings by using clang-cl
(as suggested in this SO question and here), however, I do not want to do that without fully understanding the implications.
So here are my actual questions:
- What do these warnings mean or what is causing them?
- What does using
clang-cl
change and what do I have to keep in mind when using it? (I guess there is a reason to not use it all the time) - Are there other ways to not receive these warnings (except for turning off warnings)?
I ran into this issue myself and did some investigation.
What do these warnings mean?
There is a detailed answer here (that I do not fully understand), but the high level idea, as I understand it, is there is a mismatch between the object file (
.o
file) thatclang
compiled and the library file (.lib
file) that is being linked with.Therefore, although the program seems to work, it's probably a bad idea to just ignore the warnings.
What is causing them?
The warning is being issued by the Microsoft linker,
link.exe
, whichclang
invokes. Clang does not include its own linker. By default, on Windows, it looks for the Microsoft Visual Studio C compiler headers, libraries, and linker. You can see exactly what it is doing by adding the-v
(verbose) switch to theclang
command line.I'm not sure how Clang finds these tools. I'd forgotten I even had them installed, and they certainly are not on the
PATH
. I think Clang must have dug them out of the registry somehow.What does using clang-cl change?
It changes the switches passed to the Clang compiler (also called
clang
orclang++
orclang-cl
, but with the-cc1
switch passed) and the linker (MSVClink.exe
). At a high level,clang-cl
tries to emulate the MSVCcl.exe
compiler, whileclang
... does something else. I'm not sure what. It's not emulating MinGW; see below.The detailed differences can be seen in the respective
-v
outputs. Usingclang++
andclang-cl
from LLVM 8.0.1, I see these compiler switch differences:And during linking,
clang++
passes-defaultlib:libcmt
, whileclang-cl
does not.The big difference I see is
clang-cl
passes-D_MT
, enabling the thread-aware C and C++ standard libraries. I think it's a bad idea to mix modules compiled with and without_MT
. The mismatch regarding-fcxx-exceptions
is also concerning, suggesting that C++ exceptions might not work.clang-cl
also passes-flto-visibility-public-std
, the flag recommended by this answer to a related question. I don't know whether this flag is merely suppressing a warning or significantly changing the way the code is compiled.What do I have to keep in mind when using it?
As I understand it, you want to use
clang-cl
if and only if you want Clang to do its best to emulate the Microsoftcl.exe
compiler, including using its header files and invoking the Microsoft linker with its libraries.Furthermore, I'm unaware of a reason to use
clang++
on Windows without also specifying-target
(next section). Without-target
,clang++
still uses the MSVC headers, libraries, and linker, but does not pass the switches needed to emulate thecl.exe
compiler. I suspect this will always result in an executable with mismatched object code.Are there other ways to not receive these warnings?
In my case, I want Clang to emulate the MinGW
gcc
compiler and invoke its linker instead. To do that, per this answer, add-target x86_64-pc-windows-gnu
to theclang++
command line:That command produces no warnings, and a working executable.
By adding
-v
to that command line, you can see the details, including invocation of the MinGWld.exe
linker.Note: You need a MinGW
gcc
on yourPATH
!What about clang versus clang++?
Like
gcc
,clang
will compile C++ code if the file uses an extension it recognizes, such as.cc
or.cpp
. However, it does not pass the C++ standard library to the linker, even when you compile and link in a single command. Therefore, it's generally best to useclang++
exclusively when working with C++ code.Likewise,
clang -x c++
can be used to compile C++, but again does not pass the C++ standard library to the linker.