0

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

I know that these are for linking with msvcrt or libcmt. So basically they determine which C library will be linked in at the linking stage. But do they affect the generated code in any way?

The reason I'm asking this because my code can be compiled as a .dll or a .lib. Currently, I build twice (one with /MD and one with /MT). Is it possible to optimize this, so I build object files just once (without /MT or /MD), and supply these options only at the linking stage?

geza
  • 28,403
  • 6
  • 61
  • 135
  • /MT is an optimization for very small single module programs, the CRT gets linked into the final EXE file. /MD is always required when the final program is made from multiple modules, one or more DLLs. It ensures CRT state is shared. Most basic example is `errno`. A simple variable with /MT but a function call with /MD to get to the one-and-only value. So no, not something that can be delayed until the link stage, different code. When you build a DLL then you of course *must* use /MD. When you build a static .lib then you don't know what is going to happen so must build all flavors. – Hans Passant Aug 03 '18 at 10:29
  • @HansPassant: thank for the idea, I'll check out what happens with `errno`. – geza Aug 03 '18 at 11:55

2 Answers2

1

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.

geza
  • 28,403
  • 6
  • 61
  • 135
0

/MD(d)

Causes the application to use the multithread-specific and DLL-specific version of the run-time library. Defines _MT and _DLL and causes the compiler to place the library name MSVCRT.lib into the .obj file. [Static library for the native CRT startup for use with DLL UCRT and vcruntime.]

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

/MT(d)

Causes the application to use the multithread, static version of the run-time library. Defines _MT and 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. [Statically links the native CRT startup into your code.]

-

These compiler-flags effects the content of the .obj files.

See also here.

Amit G.
  • 2,546
  • 2
  • 22
  • 30
  • Thanks for the answer. "These compiler-flags effects the content of the .obj files." In what way? Basically that's my question. The library name which is put into the .obj file, can be overridden as far as I know. What if I compile .obj file without `/MT`, and then I link with MSVCRT.lib? Is it a problem? – geza Aug 03 '18 at 11:38
  • I asked this question, because MSDN doesn't provide an answer. My question is "do they affect the generated code in any way?" Your answer and MSDN don't answer this. Linking is a different thing than code generation. – geza Aug 03 '18 at 11:44
  • @geza I'm not speaking about linking. But about compiling. In /MD the comiler place the MSVCRT.lib into the .obj file vs in /MT it place the LIBCMT.lib into the.obj file. – Amit G. Aug 03 '18 at 11:52
  • Yes, but this is not code generation. That option can be overridden by a linker option as far as I know. And if with overridden libraries, this can work, then I don't need to compile twice. – geza Aug 03 '18 at 11:54
  • @geza If you say so, maybe. I don't understand how; what I read is that the compiler prepare for the linker two different .obj files. – Amit G. Aug 03 '18 at 11:59