Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我应该用/MD还是/MT编译?_C++_Visual Studio_Msbuild_Msvcrt_Crt - Fatal编程技术网

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

C++ 我应该用/MD还是/MT编译?,c++,visual-studio,msbuild,msvcrt,crt,C++,Visual Studio,Msbuild,Msvcrt,Crt,在VisualStudio中,有编译标志/MD和/MT,可以让您选择所需的C运行库类型 我理解实现上的差异,但我仍然不确定使用哪一个。利/弊是什么 我听说,/MD的一个优点是,它允许某人更新运行时(比如可能修补安全问题),我的应用程序将受益于此更新。虽然对我来说,这似乎是一个非功能:我不希望人们在不允许我测试新版本的情况下更改我的运行时 有些事情我很好奇: 这将如何影响构建时间?(推测/MT稍微慢一点?) 其他的含义是什么 大多数人用哪一种 我认为通过VisualStudio构建的项目默认为/

在VisualStudio中,有编译标志/MD和/MT,可以让您选择所需的C运行库类型

我理解实现上的差异,但我仍然不确定使用哪一个。利/弊是什么

我听说,/MD的一个优点是,它允许某人更新运行时(比如可能修补安全问题),我的应用程序将受益于此更新。虽然对我来说,这似乎是一个非功能:我不希望人们在不允许我测试新版本的情况下更改我的运行时

有些事情我很好奇:

  • 这将如何影响构建时间?(推测/MT稍微慢一点?)
  • 其他的含义是什么
  • 大多数人用哪一种

我认为通过VisualStudio构建的项目默认为/MD

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

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

另外,正如所指出的,保持一致性是至关重要的。如果要与其他库链接,则需要使用与它们相同的选项。如果您使用的是第三方DLL,几乎可以肯定您将需要使用运行库的DLL版本。

来源:

/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使用与Y-STATICECPCPIIB定义的(/DyStistaCpPLIB)时,它将导致应用程序与静态多线程标准C++库(LIbCPMT .LIB)链接而不是动态版本(MVCPRPR.LIB),而仍然通过MSVCRT。


因此,如果我正确地解释了它,那么/MT静态链接和/MD动态链接。

通过与/MD动态链接

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

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

我更喜欢使用/MT静态链接

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


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

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


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

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

如果对.exe和所有.dll使用动态CRT,则它们将共享CRT的单个实现-这意味着它们将共享单个CRT堆,并且在一个.exe/.dll中分配的内存可以在另一个.exe/.dll中释放


如果您对.exe和所有.dll使用静态CRT,那么它们都将获得CRT的单独副本-这意味着它们都将使用自己的CRT堆,因此必须在分配内存的同一模块中释放内存。您还将遭受代码膨胀(CRT的多个副本)和过多的运行时开销(每个堆从操作系统分配内存以跟踪其状态,开销是显而易见的).

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

如果你的可执行文件没有使用任何lib或dll,那么它的调用就是anywhere。现在差别不大,因为共享方面没有发挥作用


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

系统更新位会因SxS而有所减少。EXE可以声明它想要的CRT版本(需要,而不是获取-安全更新可能会否决这一点)这是否意味着如果我使用MD编译,并且我的程序依赖于某个dll,那么如果程序运行在