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) that clang
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
, which clang
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 the clang
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
or clang++
or clang-cl
, but with the -cc1
switch passed) and the linker (MSVC link.exe
). At a high level, clang-cl
tries to emulate the MSVC cl.exe
compiler, while clang
... 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. Using clang++
and clang-cl
from LLVM 8.0.1, I see these compiler switch differences:
clang-cl has but clang++ lacks:
-relaxed-aliasing
-mllvm
-x86-asm-syntax=intel
-D_MT
-flto-visibility-public-std
--dependent-lib=libcmt
--dependent-lib=oldnames
-stack-protector 2
-fms-volatile
-fdiagnostics-format msvc
clang++ has but clang-cl lacks:
-fcxx-exceptions
-fexceptions
And during linking, clang++
passes -defaultlib:libcmt
, while clang-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 Microsoft cl.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 the cl.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 the clang++
command line:
$ clang++.exe -target x86_64-pc-windows-gnu -o cpphello.exe cpphello.cpp
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 MinGW ld.exe
linker.
Note: You need a MinGW gcc
on your PATH
!
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 use clang++
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.