-> /MD, /MT these options, you can select either single-threaded or multi threaded
run-time routines, indicate that a multi threaded module is a
dynamic-link library (DLL), and select the retail or debug version of
the library.
Note:
Having
more than one copy of the run-time libraries in a process can cause
problems, because static data in one copy is not shared with the
other copy. To ensure that your process contains only one copy, avoid
mixing static and dynamic versions of the run-time libraries. The
linker will prevent you from linking with both static and dynamic
versions within one .EXE file, but you can still end up with two (or
more) copies of the run-time libraries. For example, a dynamic-link
library linked with the static (non-DLL) versions of the run-time
libraries can cause problems when used with an .EXE file that was
linked with the dynamic (DLL) version of the run-time libraries. (You
should also avoid mixing the debug and non-debug versions of the
libraries in one process.)
Command Line
|
Project Settings
|
Description
|
/MD
|
Multithreaded DLL
|
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 MSVCRT.DLL, which must be
available at run time to applications linked with MSVCRT.LIB.
|
/MDd
|
Debug Multithreaded DLL
|
Defines _DEBUG, _MT,
and _DLL so
that debug multithread- and DLL-specific versions of the run-time
routines are selected from the standard .H files. It also causes
the compiler to place the library name MSVCRTD.LIB into the .OBJ
file.
|
/ML
|
Single-Threaded
|
Causes the compiler to place the library
name LIBC.LIB into the .OBJ file so that the linker will use
LIBC.LIB to resolve external symbols. This is the compiler’s
default action. LIBC.LIB does not provide multithread support.
|
/MLd
|
Debug Single-Threaded
|
Defines _DEBUG and
causes the compiler to place the library name LIBCD.LIB into the
.OBJ file so that the linker will use LIBCD.LIB to resolve
external symbols. LIBCD.LIB does not provide multithread support.
|
/MT
|
Multithreaded
|
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.
|
/MTd
|
Debug Multithreaded
|
Defines _DEBUG and _MT.
Defining _MT causes
multithread-specific versions of the run-time routines to be
selected from the standard .H files. This option also causes the
compiler to place the library name LIBCMTD.LIB into the .OBJ file
so that the linker will use LIBCMTD.LIB to resolve external
symbols. Either /MTd or /MDd (or their non-debug equivalents /MT
or MD) is required to create multithreaded programs.
|
/LD
|
Not applicable
|
Creates a DLL. Passes the /DLL
option to the linker. The linker looks for, but does not require,
aDllMain function.
If you do not write a DllMain function,
the linker inserts a DllMainfunction
that returns TRUE. Links the DLL startup code. Creates
an import library (.LIB), if an export (.EXP) file is not
specified on the command line; you link the import library to
applications that call your DLL. Interprets /Fe as
naming a DLL rather than an .EXE file; the default program name
becomes basename.DLL
instead of basename.EXE. Changes
default run-time library support to /MT if you have not explicitly
specified one of the /M options
|
/LDd
|
Not applicable
|
Creates a debug DLL. Defines _DEBUG.
|
To
find these options in the development environment, click Settings on
the Project menu.
Then click the C/C++ tab,
and click Code
Generation in
theCategory box.
See the Use
Run-Time Library drop-down
box.
The
debug options select the debug versions of the library or DLL and
define _DEBUG.
For more information on using the debug versions, see C
Run-Time Debug Libraries.
Run-Time
Library Behavior:
The
C/C++ run-time library code performs the DLL startup sequence,
eliminating the need to link with a separate module as was necessary
in Windows 3.x. Included in the C/C++ run-time library code is the
DLL entry-point function called _DllMainCRTStartup.
The _DllMainCRTStartup function
does several things, including calling CRT_INIT,
which initializes the C/C++ run-time library and invokes C++
constructors on static, non-local variables. Without this function,
the run-time library would be left in an uninitialized state.
While
it is possible to specify another entry-point function using the
/ENTRY: linker switch, it is not recommended because your entry-point
function would have to duplicate everything
that _DllMainCRTStartup does.
When building DLLs in Visual C++, _DllMainCRTStartup is
linked in automatically and you do not need to specify an entry-point
function using the /ENTRY: linker switch .
In
addition to initializing the C run-time
library, _DllMainCRTStartup calls
a function called DllMain.
Depending on the kind of DLL you are building, Visual C++
provides DllMain for
you and it gets linked in so that _DllMainCRTStartup always
has something to call. In this way, if you do not need to initialize
your DLL, there's nothing special you have to do when building your
DLL. If you need to initialize your DLL, where you add your code
depends on the kind of DLL you are writing. See Initialize
a DLL for
more information.
The
C/C++ run-time library code calls constructors and destructors on
static, non-local variables. For example, in the following DLL source
code, Equus
andSugar
are
two static, non-local objects of class CHorse
,
defined in HORSES.H. There is no function in source code that
contains calls to a constructor function for CHorse
or
to the destructor function because these objects are defined outside
of any function. Therefore, calls to these constructors and
destructors must be performed by the run-time code. (The run-time
library code for applications also performs this function.)
#include "horses.h"
CHorse Equus( ARABIAN, MALE );
CHorse Sugar( THOROUGHBRED, FEMALE );
BOOL WINAPI DllMain (HANDLE hInst,
ULONG ul_reason_for_call,
LPVOID lpReserved)
.
.
.
Each
time a new process attempts to use the DLL, the operating system
creates a separate copy of the DLL's data: this is called "process
attach". The run-time library code for the DLL calls the
constructors for all the global objects, if any, and then calls
the DllMain function
with process attach selected. The opposite situation is process
detach: the run-time library code calls DllMain with
process detach selected and then calls a list of termination
functions including atexit functions,
destructors for the global objects, and destructors for the static
objects. Note that the order of events in process attach is the
reverse of that in process detach.
The
run-time library code is also called during thread attach and thread
detach, but the run-time code does no initialization or termination
on its own.
Linking
with MD has advantages:
1
- Different modules (i.e. DLLs or EXEs) can exchange "memory
ownership". For example, a memory allocated through new/malloc
in one module can be reallocated/deleted/freed by another. This is
very helpful if you use STL in the interface between your modules.
2
- The runtime has some "global data". Linking with MT means
that this "global data" will not be shared, while with MD,
it will be shared. This means that with MD, you can pass some data
from one module to another without risk.
3
- 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).
Linking with MD has disadvantages:
1. while
a module compiled with MD will link with a DLL at the moment of
execution. if DLL will not found in the machine then your application will be crashed.
Linking with MT has advantages:
1. 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. Module you compiled with MT will have the runtime "inside it", while a module compiled with MD will link with a DLL at the moment of execution.
Note:
->Anyway, a release and debug versions of the same module should link with the same category of runtime. If your release links with MT, then your debug should link with MTd. In the same way, if your release links with MD, your debug should link with MDd.
-> Now, you should avoid mixing in the same process different modules linked with different run times (Note that the release and debug run times are different run times). violating this rule could lead to mysterious crashes.
For example, say you have MyExe.exe which links with MyDll.dll : You should avoid mixing a release version of MyExe.exe and an debug version of MyDllD.dll. In the same way, you should avoid mixing a MT compiled MyExe.exe and a MD compiled MyDll.dll.
-> 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).
-> Typical
solutions to this are to have the user install the appropriate MSVC
redistributable package, or use an installer that does all the work
-> I
believe the default for projects built through Visual Studio is /MD.
-> 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).