Should I Compile With /Md or /Mt

Should I compile with /MD or /MT?

By dynamically linking with /MD,

  • you are exposed to system updates (for good or ill),
  • your executable can be smaller (since it doesn't have the library embedded in it), and
  • I believe that at very least the code segment of a DLL is shared amongst all processes that are actively using it (reducing the total amount of RAM consumed).

I've also found that in practice, when working with statically-linked 3rd-party binary-only libraries that have been built with different runtime options, /MT in the main application tends to cause conflicts much more often than /MD (because you'll run into trouble if the C runtime is statically-linked multiple times, especially if they are different versions).

What does MT and MD stand for?

DLL and internal may be used as mnemonic to distinguish /MD from /MT.

What difference does /MD, /MT make when compiling object files?

Yes, these options affect the generated code a little bit. Look at this simple code:

#include <errno.h>

int fn() {
return errno;
}

With /MT, this compiles:

call    __errno
mov eax, DWORD PTR [eax]

While with /MD:

call    DWORD PTR __imp___errno
mov eax, DWORD PTR [eax]

So, DLL imported symbols will have a __imp_ prefix, and they are actually a pointer to the real symbol.

Conceptual ambiguity between /MD /MT and dll lib

A key aspect of this is differentiating between the build/compile time issues and the runtime issues.

At build time, the compiler and linker need sufficient information on how to compile and construct the code; data definitions, function locations etc. The header files provide most of that detail for the compiler, the linker needs to be able to locate the functions1 to complete the process.

If the dll is provided with a lib as well (as is the case with /MD), this lib contains the minimum required code for the linker to find the functions required and some additional code to load the dll at runtime. A program can be made that does not link with a lib (even though there is a dll), you will then need to load the dll at runtime (via LoadLibrary) and fix up the pointers (via GetProcAddress) to the functions1 you need to call. With a C++ library that is difficult, hence it is generally not attempted, the name mangling make this harder (with a C library it is generally much easier).

If the lib is a static lib with no associated dll (for the runtime this is /MT), then the lib contains all the code needed to run and execute its given functionality. The linker links all the required code up into the target and no additional runtime loading is required.

1 I loosely use the word functions here, but it includes all externals as well.

MT and MD on Linux

/MT and /MD are not really Windows, but Visual Studio. While both are from Microsoft, there is a very important distinction. The two products are far more separated than is typically the case on Linux.

In particular, on Linux it's never been clear whether libc is part of the OS, or part of the C compiler. That didn't really matter much, though as C didn't evolve that fast anyway.
The real problem on Linux is libstdc++, which depends on libc, and as such got dragged into the same dependency issue.

The result is that Visual Studio 2019 can compile C++20 code for Windows XP, and with /MT it will just work. But compile on Debian 10, and you'll get a dependency on the Debian 10 libc which won't even work on Debian 9.

mixing code compiled with /MT and /MD

No. /MT and /MD are mutually exclusive.

All modules passed to a given invocation of the linker must have been compiled with the same run-time library compiler option (/MD, /MT, /LD).

Source

How to tell if a lib was compiled with /mt or /md?

Yes, you could use dumpbin's /DIRECTIVES option to find which runtime libraries the objects in the .lib want to link with:

dumpbin /directives foo.lib

Look for instances of the runtime libraries specified here. For example, you might see:

/DEFAULTLIB:MSVCRTD (module compiled with /MDd)

or

/DEFAULTLIB:MSVCRT (module compiled with /MD)

or

/DEFAULTLIB:LIBCMT (module compiled with /MT)

There will probably be many /DEFAULTLIB directives, so you can search using terms like:

dumpbin /DIRECTIVES foo.lib | find /i "msvcr"

if I change runtime library to MD, should I re-compile ALL MT libraries to MD?

You almost certainly want to use consistent runtime libraries otherwise all kinds of horrible things can happen. You might get away with it depending on what you are using from the library, but it's probably a bad idea.


MT is multithreaded static and MD is multithreaded dynamic.
The docs say

"All modules passed to a given invocation of the linker must have been
compiled with the same run-time library compiler option (/MD, /MT,
/LD)."



Related Topics



Leave a reply



Submit