VC的/MT和/MD编译选择

经常使用 Visual Studio 编译程序,经常被一些莫名其妙的错误搞懵,特别是提示链接库时候MT(d)或者MD(d)不对应,下面针对二者的区别简单介绍(带d的是对应的Debug版本)。

主要区别

首先看下二者的定义

  • /MD 表示多线程 DLL 版本,运行时库由 DLL 提供,即我们常说的动态链接态

  • /MT 表示多线程静态版本,程序不需要额外的 DLL,即我们常说的静态链接

同时,在编译器中针对不同的选择(包括 Debug 版本)提供了不同的定义,详细如下

选项 包含宏 链接库
/MD _MT _DLL msvcrt.lib
/MDd _DEBUG _MT _DLL msvcrtd.lib
/MT _MT libcmt.lib
/MTd _DEBUG _MT libcmtd.lib

看到上面的库名称应该很熟悉了,经常在编译警告中见到。/MD/MDd 版本的运行需要对应的 DLL,即 msvcr80.dll 以及 msvcr80d.dll ,数字代表了 Visual Studio 的版本,比如 Visual Studio 2010 是 10。

参考:https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=vs-2017

很多优秀的第三方库都提供了两种方式,比如boost,链接库的 /MT 版本文件名带 mt 字样。

编译选择

首先必须明确一点,就是不能同时链接这两种库,因为实现不一样,绝对不能混用。那么应该选哪个呢?

选择/MD的时候

  • 可明显减少软件大小,毕竟很多动态库是共用的,也是现在推荐的方式

  • 使用上,在内存申请上是相同的堆空间,不存在其他问题

选择/MT的时候

  • 可以减少部署依赖缺失或版本不对应的问题

选/MT时候需要注意,各个运行库的堆空间不同,内存谁申请谁释放

其他说明

编译运行库选项的修改位置

Visual Studio 中修改上述选项的位置在,属性 - C/C++ - 代码生成 - 运行库,注意 Debug 和 Release 不同配置。

其他运行库选项

上面的两个选项,都定义了 _MT 也就是说上述两个库都是多线程版本的,但其实还有个 /LD 的选项,暂且不论。

PS: 博客主题的表格样式终于弄好了,看着还行!

最近的文章

SQLite一些技巧

SQLite是简单的嵌入式关系型数据,因而与其他大型的关系型数据库的操作规则有很大的区别,本文是持续更新的关于SQLite的一些规则总结。 定义方面自增字段SQLite的自增字段只支持 INTEGER 类型,使用 AUTOINCREMENT 关键字 create table t1(id INTEGE …

技术 继续阅读
更早的文章

编译数据库开发库SOCI

SOCI是一个比较不错的C++使用的数据库操作库,封装了常见的多种数据库。Linux上安装较为简单,在官方仓库即有开发的安装包,因此在此记录Win32上使用Visual Studio编译源码的方法,并以最简单的Sqlite3后端数据库为例。 安装Sqlite3SQLite是一个小巧流行的嵌入式数据库 …

技术 继续阅读