C++ 我应该用 /MD 还是 /MT 编译?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/757418/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Should I compile with /MD or /MT?
提问by andy
In Visual Studio, there's the compile flags /MD and /MT which let you choose which kind of C runtime library you want.
在 Visual Studio 中,有编译标志 /MD 和 /MT,可让您选择所需的 C 运行时库类型。
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!
我听说 /MD 的一个优点是它允许某人更新运行时(例如可能修补安全问题)并且我的应用程序将从此更新中受益。尽管对我来说,这几乎似乎是一个非功能:我不希望人们在不让我测试新版本的情况下更改我的运行时!
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?
- 这将如何影响构建时间?(大概 /MT 会慢一点?)
- 其他含义是什么?
- 大多数人使用哪一种?
采纳答案by Mr Fooz
By dynamically linking with /MD,
通过与 /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).
- 您接触到系统更新(无论好坏),
- 您的可执行文件可以更小(因为它没有嵌入库),并且
- 我相信至少 DLL 的代码段在所有积极使用它的进程之间共享(减少消耗的 RAM 总量)。
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).
我还发现,在实践中,当使用使用不同运行时选项构建的静态链接的 3rd 方仅二进制库时,主应用程序中的 /MT 往往比 /MD 更容易引起冲突(因为你如果 C 运行时被多次静态链接,则会遇到麻烦,尤其是当它们是不同的版本时)。
回答by JoeG
If you are using DLLs then you should go for the dynamically linked CRT (/MD).
如果您使用的是 DLL,那么您应该选择动态链接的 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.
如果您对 .exe 和所有 .dll 使用动态 CRT,那么它们都将共享 CRT 的单一实现 - 这意味着它们都将共享单个 CRT 堆,并且可以在一个 .exe/.dll 中释放分配的内存其他。
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).
如果您对 .exe 和所有 .dll 使用静态 CRT,那么它们都将获得 CRT 的单独副本 - 这意味着它们都将使用自己的 CRT 堆,因此必须在其所在的同一模块中释放内存被分配。您还将遭受代码膨胀(CRT 的多个副本)和过多的运行时开销(每个堆从操作系统分配内存以跟踪其状态,并且开销可能很明显)。
回答by Mark Ransom
I believe the default for projects built through Visual Studio is /MD.
我相信通过 Visual Studio 构建的项目的默认值是 /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.
如果您使用 /MT,您的可执行文件将不依赖于目标系统上存在的 DLL。如果您将其包装在安装程序中,则可能不会有问题,您可以采用任何一种方式。
I use /MT myself, so that I can ignore the whole DLL mess.
我自己使用 /MT,这样我就可以忽略整个 DLL 混乱。
P.S. As Mr. Foozpoints 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.
PS 正如Fooz 先生指出的那样,保持一致是至关重要的。如果您要与其他库链接,则需要使用与它们相同的选项。如果您使用第三方 DLL,几乎可以肯定您需要使用运行时库的 DLL 版本。
回答by Adrian Grigore
I prefer to link statically with /MT.
我更喜欢与 /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.
即使您使用 /MD 获得了较小的可执行文件,您仍然需要提供一堆 DLL 以确保用户获得正确的版本来运行您的程序。最后,您的安装程序将比使用 /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.
更糟糕的是,如果您选择将运行时库放在 windows 目录中,用户迟早会安装具有不同库的新应用程序,如果运气不好,会破坏您的应用程序。
回答by i_am_jorf
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).
使用 /MD 会遇到的问题是 CRT 的目标版本可能不在您的用户计算机上(特别是如果您使用的是最新版本的 Visual Studio 并且用户使用的是较旧的操作系统)。
In that case you have to figure out how to get the right version onto their machine.
在这种情况下,您必须弄清楚如何将正确的版本安装到他们的机器上。
回答by lothar
from http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx:
来自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.
/MT 定义 _MT,以便从标准头 (.h) 文件中选择运行时例程的多线程特定版本。此选项还会导致编译器将库名 LIBCMT.lib 放入 .obj 文件中,以便链接器将使用 LIBCMT.lib 来解析外部符号。创建多线程程序需要 /MT 或 /MD(或它们的调试等效项 /MTd 或 /MDd)。
/MD 定义 _MT 和 _DLL,以便从标准 .h 文件中选择多线程和 DLL 特定版本的运行时例程。此选项还会导致编译器将库名 MSVCRT.lib 放入 .obj 文件中。
使用此选项编译的应用程序静态链接到 MSVCRT.lib。该库提供了一层代码,允许链接器解析外部引用。实际工作代码包含在 MSVCR71.DLL 中,它必须在运行时对与 MSVCRT.lib 链接的应用程序可用。
当 /MD 与定义的 _STATIC_CPPLIB (/D_STATIC_CPPLIB) 一起使用时,它将导致应用程序链接到静态多线程标准 C++ 库 (libcpmt.lib) 而不是动态版本 (msvcprt.lib),同时仍然通过以下方式动态链接到主 CRT msvcrt.lib。
So if I am interpreting it correctly then /MTlinks statically and /MDlinks dynamically.
因此,如果我正确解释它,那么/MT静态链接和/MD动态链接。
回答by zar
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.
如果您正在构建使用其他 dll 或库的可执行文件,而不是 /MD 选项是首选,因为这样所有组件都将共享相同的库。当然,这个选项应该匹配所有涉及的模块,即 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.
如果您的可执行文件不使用任何 lib 或 dll,而不是任何人的调用。现在差别不大,因为共享方面没有发挥作用。
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.
因此,也许您可以使用 /MT 启动应用程序,因为没有其他令人信服的理由,但是当需要添加 lib 或 dll 时,您可以使用 lib/dll 将其更改为 /MD,这很容易。