我应该用/MD 还是/MT 编译?

在 Visual Studio 中,有编译标志/MD 和/MT,它们允许您选择所需的 C 运行时库类型。

我明白在实现上的区别,但是我仍然不确定使用哪一个。优缺点是什么?

我听说/MD 的一个优点是,它允许用户更新运行时(比如修补安全问题) ,我的应用程序将从这次更新中受益。尽管对我来说,这似乎是一个非特性: 我不希望人们改变我的运行时,而不允许我对新版本进行测试!

有些事情我很好奇:

  • 这将如何影响构建时间? (大概/MT 会稍微慢一点?)
  • 还有什么其他含义?
  • 大多数人使用哪一种?
103353 次浏览

我相信通过 VisualStudio 构建的项目的默认值是/MD。

如果使用/MT,则可执行文件将不依赖于目标系统上存在的 DLL。如果你在安装程序中包装这个,这可能不会是一个问题,你可以选择任何一种方式。

我自己使用/MT,这样我就可以忽略整个 DLL 混乱。

附言。正如 福兹先生指出的那样,保持一致至关重要。如果要链接其他库,则需要使用与它们相同的选项。如果使用第三方 DLL,那么几乎可以肯定需要使用运行时库的 DLL 版本。

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

/MT Definition _ MT,以便从标准头(。H)档案。此选项还使编译器将库名称 LIBCMT.lib 放入。Obj 文件,以便链接器使用 LIBCMT.lib 解析外部符号。创建多线程程序需要/MT 或/MD (或它们的调试等价物/MTd 或/MDd)。

/MD 定义 _ MT 和 _ DLL,以便从标准中选择特定于多线程和 DLL 的运行时例程版本。H 档案。此选项还会导致编译器将库名称 MSVCRT.lib 放入。Obj 文件。

使用此选项编译的应用程序静态链接到 MSVCRT.lib。此库提供了一层代码,允许链接器解析外部引用。实际的工作代码包含在 MSVCR71.DLL 中,它必须在运行时对与 MSVCRT.lib 链接的应用程序可用。

当/MD 与定义的 _ STATIC _ CPPLIB (/D _ STATIC _ CPPLIB)一起使用时,它将导致应用程序链接到静态多线程标准 C + + 库(libcpmt.lib)而不是动态版本(msvcprt.lib) ,同时仍然通过 msvcrt.lib 动态链接到主 CRT。

因此,如果我正确地解释它,然后 /MT静态链接和 海事处动态链接。

通过动态链接/MD,

  • 你暴露在系统更新中(无论是好是坏) ,
  • 您的可执行文件可以更小(因为它没有嵌入库) ,并且
  • 我相信至少 DLL 的代码段可以在所有正在使用它的进程之间共享(减少了所消耗的 RAM 总量)。

我还发现,在实践中,当使用使用不同运行时选项构建的静态链接的第三方二进制库时,主应用程序中的/MT 往往比/MD 更容易引起冲突(因为如果 C 运行时是静态链接的多次,特别是如果它们是不同的版本,你就会遇到麻烦)。

我更喜欢静态链接/MT。

即使您使用/MD 获得了一个较小的可执行文件,您仍然需要提供大量的 DLL,以确保用户获得正确的版本来运行您的程序。最后,您的安装程序将比链接/MT 时更大。

更糟糕的是,如果您选择将运行时库放在 windows 目录中,用户迟早会安装一个具有不同库的新应用程序,如果运气不好,就会破坏您的应用程序。

使用/MD 时会遇到的问题是,CRT 的目标版本可能不在用户机器上(特别是如果您使用的是最新版本的 Visual Studio,而用户使用的是较旧的操作系统)。

在这种情况下,您必须弄清楚如何将正确的版本放到他们的机器上。

如果您使用的是 DLL,那么您应该使用动态链接的 CRT (/MD)。

如果将动态 CRT 用于。还有前妻什么的。Dlls 然后它们将共享 CRT 的单个实现-这意味着它们将共享一个单独的 CRT 堆和分配在一个堆中的内存。Exe/.Dll 可以在另一个中释放。

如果您使用静态 CRT。还有前妻什么的。Dlls 会得到 CRT 的一个独立副本,这意味着它们都使用自己的 CRT 堆,因此内存必须在分配它的同一个模块中释放。您还会遇到代码膨胀(CRT 的多个副本)和额外的运行时开销(每个堆从操作系统分配内存以跟踪其状态,这些开销可能是显而易见的)。

如果您正在构建使用其他 dlls 或 libs 的可执行文件,则首选/MD 选项,因为这样所有组件将共享相同的库。当然,这个选项应该匹配所有涉及的模块,即 dll/lib/exe。

如果您的可执行文件不使用任何 lib 或 dll 而不使用任何人的调用。现在差别不是很大,因为共享方面没有发挥作用。

因此,也许你可以使用/MT 来启动应用程序,因为没有其他令人信服的理由,但是当它需要添加一个 lib 或 dll 时,你可以使用 lib/dll 来将它改为/MD,这很容易。