133

In Visual Studio, there's the compile flags /MD and /MT which let you choose which kind of C runtime library you want.

I understand the difference in implementation, but I'm still not sure which one to use. What are the pros/cons?

One advantage to /MD that I've heard, is that this allows someone to update the runtime, (like maybe patch a security problem) and my app will benefit from this update. Although to me, this almost seems like a non-feature: I don't want people changing my runtime without allowing me to test against the new version!

Some things I am curious about:

  • How would this affect build times? (presumably /MT is a little slower?)
  • What are the other implications?
  • Which one do most people use?
andy
  • 16,174
  • 9
  • 28
  • 27

7 Answers7

91

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).

Mr Fooz
  • 95,588
  • 5
  • 65
  • 95
  • 11
    The system updates bit is somewhat reduced by SxS. The EXE gets to declare which CRT version it wants (wants, not gets - security updates might overrule this) – MSalters Apr 17 '09 at 13:49
  • 1
    Does this mean if I compile using MD and my program is dependant on some dll, the program will fail if it's running on a computer where the dependency dll is non-existent? – gerrytan Oct 03 '13 at 05:09
  • 5
    @gerrytan: Yes, you'll need to ensure that the appropriate DLLs being used are present on all computers that want to run the software. Typical solutions to this are to have the user install the appropriate MSVC redistributable package, or use an installer that does all the work. – Mr Fooz Oct 03 '13 at 17:24
  • @Royi I'm not sure but I think `/MT` will be slightly faster at runtime since your app don't need to search for the runtime function's implementation each time, I'm not an expert at this level but I'm pretty sure most of OSs will cache the runtime implementations so your app will use the cached version, so the difference will not be that far, NOTE that I mentioned that I'm not sure so don't take this comment as an argument. – Ahmed Kamal Jul 30 '19 at 07:21
41

If you are using DLLs then you should go for the dynamically linked CRT (/MD).

If you use the dynamic CRT for your .exe and all .dlls then they will all share a single implementation of the CRT - which means they will all share a single CRT heap and memory allocated in one .exe/.dll can be freed in another.

If you use the static CRT for your .exe and all .dlls then they'll all get a seperate copy of the CRT - which means they'll all use their own CRT heap so memory must be freed in the same module in which it was allocated. You'll also suffer from code bloat (multiple copies of the CRT) and excess runtime overhead (each heap allocates memory from the OS to keep track of its state, and the overhead can be noticeable).

JoeG
  • 12,484
  • 1
  • 34
  • 62
23

I believe the default for projects built through Visual Studio is /MD.

If you use /MT, your executable won't depend on a DLL being present on the target system. If you're wrapping this in an installer, it probably won't be an issue and you can go either way.

I use /MT myself, so that I can ignore the whole DLL mess.

P.S. As Mr. Fooz points out, it's vital to be consistent. If you're linking with other libraries, you need to use the same option they do. If you're using a third party DLL, it's almost certain that you'll need to use the DLL version of the runtime library.

Community
  • 1
  • 1
Mark Ransom
  • 271,357
  • 39
  • 345
  • 578
15

I prefer to link statically with /MT.

Even though you do get a smaller executable with /MD, you still have to ship a bunch of DLLs to make sure the user gets the right version for running your program. And in the end your installer is going to be BIGGER than when linking with /MT.

What's even worse, if you choose to put your runtime libraries in the windows directory, sooner or later the user is going to install a new application with different libraries and, with any bad luck, break your application.

Adrian Grigore
  • 31,759
  • 32
  • 127
  • 205
  • 5
    Very bad idea to "put your runtime libraries in the windows directory". You can break other dumb applications that did the same before you did. Use SxS and let the installer handle it, or stick with /MT. – MSalters Apr 17 '09 at 13:51
  • 1
    I fully agree that it's a bad Idea. Some people do it though, so I was describing why this is not a good idea. – Adrian Grigore Apr 18 '09 at 09:06
  • @AdrianGrigore why would a new application with different libraries cause a break in you application? If you use /MD linkage, you would just start loading the new versions of the libraries right? – rturrado Sep 17 '12 at 16:12
  • 4
    @rturrado: not quite. Installing other applications on top of yours might overwrite your dlls with older versions. The newer versions would be gone. This is commonly known as "dll hell", see http://en.wikipedia.org/wiki/DLL_Hell – Adrian Grigore Sep 18 '12 at 19:24
  • 1
    Microsoft gave up on WinSxS in Visual Studio 2010 - runtime libraries are now either deployed privately or in system32 (http://msdn.microsoft.com/en-us/library/vstudio/dd293574.aspx). – BCran Jan 23 '13 at 15:26
  • The argument for smaller EXE with /MD has nothing to do with size of installer or size on disk: it's to reduce memory consumption from OS (both from image size and shared heap). – codesniffer Oct 13 '19 at 06:14
  • The question may not depend on preferences. If you need to share filedescriptors (from fd=open), malloc pointers, etc between your DLLs and your main program, than you must use /MD. If you don't use such elements, than you can have the choice to use /MD or /MT. You may use "program with no LoadLibrary(my.DLL)" -> /MT to avoid DLLs vodoo You must use "program with LoadLibaryr(my.DLL) and sharing mcvcrt handles" -> /MD and redist.exe installation at delivery. https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-160 – bernie3280109 Mar 24 '21 at 15:30
8

The problem you will run into with /MD is that the target version of the CRT may not be on your users machine (especially if you're using the latest version of Visual Studio and the user has an older operating system).

In that case you have to figure out how to get the right version onto their machine.

i_am_jorf
  • 51,120
  • 15
  • 123
  • 214
5

from http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx:

/MT Defines _MT so that multithread-specific versions of the run-time routines are selected from the standard header (.h) files. This option also causes the compiler to place the library name LIBCMT.lib into the .obj file so that the linker will use LIBCMT.lib to resolve external symbols. Either /MT or /MD (or their debug equivalents /MTd or /MDd) is required to create multithreaded programs.

/MD Defines _MT and _DLL so that both multithread- and DLL-specific versions of the run-time routines are selected from the standard .h files. This option also causes the compiler to place the library name MSVCRT.lib into the .obj file.

Applications compiled with this option are statically linked to MSVCRT.lib. This library provides a layer of code that allows the linker to resolve external references. The actual working code is contained in MSVCR71.DLL, which must be available at run time to applications linked with MSVCRT.lib.

When /MD is used with _STATIC_CPPLIB defined (/D_STATIC_CPPLIB) it will cause the application to link with the static multithread Standard C++ Library (libcpmt.lib) instead of the dynamic version (msvcprt.lib) while still dynamically linking to the main CRT via msvcrt.lib.

So if I am interpreting it correctly then /MT links statically and /MD links dynamically.

Community
  • 1
  • 1
lothar
  • 18,633
  • 5
  • 43
  • 59
2

If you are building executable that uses other dlls or libs than /MD option is preferred because that way all the components will be sharing same library. Of course this option should match for all the modules involved i.e dll/lib/exe.

If your executable doesn't uses any lib or dll than its anyone's call. The difference is not too much now because the sharing aspect is not into play.

So maybe you can start the application with /MT since there is no compelling reason otherwise but when its time to add a lib or dll, you can change it to /MD with that of the lib/dll which is easy.

zar
  • 9,241
  • 10
  • 74
  • 145