MD与MT的区别

涉及到编译qt源码中有部分编译选项中在静态编译qt源码要求把对应的-MD修改成-MT,正好记录一下-MD与-MT相关区别

MT:mutithread Static,多线程库,编译器会从运行时库中选择多线程静态库来解释程序中的代码,即链接LIBCMT.lib库
MTd:上述调试版本,LIBMITD.lib
MD:mutithread Dynamic,多线程动态库,链接MSVCRT.lib库,这是个导入库,对应动态库是MSVCRT.dll
MDd:上述版本调试版本,链接MSVCRTD.lib,对应动态库是MSVCRTD.dll

MT/MTd(静态链接)
优点:不需要在部署时包含额外的运行时库DLL文件,因为所有的运行时代码都已经包含在最终的可执行文件中。这简化了部署过程并减少了对环境的依赖。同时有轻微性能提升。
场景:当有些系统可能没有程序所需要版本的运行时库(有时候打开windows沙盒模式就会出现该问题),这样选择-MT会减少模块对外界的依赖。
缺点:是最终的可执行文件会比较大(因为把运行时库二进制也带进来了),如果项目中多个库使用了静态链接运行时库,也会出现重复的、冗余的代码占用内存。

MD/MDd(动态链接)
优点:是可执行文件体积较小,多个程序可以共享同一份运行时库的副本,节省资源。
场景:当用户不需要静态链接运行时库的时候,然后所有的模块都采用-MD的时候,使用的是同一个堆,(看其他文章,如果是-MT的情况下,一个dll内部会有一个堆(_crtheap全局变量,_heap_init就会在每个模块里都被调用一次),如果是-MD情况下,整个进程只有一个堆(整个进程里只有运行时库里才有一份_crtheap全局变量,在crt的dll加载的时候调用一次_heap_init)多个堆存在着释放崩溃的危险,a堆申请需要a堆释放)
缺点:是在部署程序时需要确保正确版本的运行时库DLL文件也被安装在目标系统上,否则程序无法运行。

在同一个项目中,所有组件使用相同的运行时库链接方式是非常重要的,主要原因是确保一致性、稳定性和避免潜在的冲突。具体来说:

  1. 对象内存管理
    不同的运行时库可能有不同的内存管理机制。如果一个对象在一个运行时库中被创建(分配内存),而在另一个运行时库中被销毁(释放内存),可能会导致内存泄漏或者更糟糕的情况。确保所有库使用相同的运行时库可以防止这种情况发生。

  2. 全局状态的一致性
    静态链接的运行时库将其全局状态编译进每个可执行文件或库中。如果一个项目中混用了静态和动态链接的运行时库,可能导致有多个独立的全局状态实例存在于同一个进程中,这会导致异常行为,比如不一致的全局变量状态、初始化和终止序列混乱等。

  3. C++异常处理
    在C++中,如果不同的组件使用了不同的运行时库,可能会导致异常处理不兼容。例如,一个用MDd编译的DLL抛出的异常可能无法被用MTd编译的可执行文件正确捕获或处理。

  4. 类型定义和实现
    运行时库通常包含了标准类型和函数的实现。如果不同的运行时库版本被混合使用,可能会导致类型定义上的冲突或者不同的实现之间的不兼容,导致运行时错误。

  5. 线程和同步对象
    多线程编程通常依赖于运行时库提供的同步机制,如互斥锁和条件变量。如果混用不同的运行时库,线程同步对象的行为可能会不一致,导致死锁或竞争条件。

  6. 依赖和链接问题
    如果项目中的不同部分链接了不同的运行时库,可能会出现难以诊断的链接错误,因为链接器可能无法解析多个版本的符号和库。

https://blog.csdn.net/hebhljdx/article/details/139917526
上面这六点来自上面链接,写的很详细

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值