文章转载自:
你所不知道的C和C++运行库_ithzhang的博客-CSDN博客_c/c++运行库
作者写的已经很清楚了,这个文章很透彻。
在各个版本的编译器中,我们可以通过配置选项来设置程序使用的C和C++运行时库的类型。如下图(其他版本编译器大同小异):
MT选项:链接LIB版的C和C++运行库。在链接时就会在将C和C++运行时库集成到程序中成为程序中的代码,程序体积会变大。
MTd选项:LIB的调试版。
MD选项:使用DLL版的C和C++运行库,这样在程序运行时会动态的加载对应的DLL,程序体积会减小,缺点是在系统没有对应DLL时程序无法运行。
MDd选项:表示使用DLL的调试版。
关于C和C++运行库的概念
为了提高C语言的开发效率,C标准定义了一系列常用的函数,称为C库函数。C标准仅仅定义了函数原型,并没有提供实现。因此这个任务留给了各个支持C语言标准的编译器。每个编译器通常实现了标准C的超集,称为C运行时库(C Run Time Library),简称CRT。对于VC++编译器来说,它提供的CRT库支持C标准定义的标准C函数,同时也有一些专门针对Windows系统特别设计的函数
与C语言类似,C++也定义了自己的标准,同时提供相关支持库,称为C++运行时库或C++标准库。由于C++对C的兼容性,C++标准库包括了C标准库,除此之外还包括了IO流和标准模板库STL。
VC++在何处实现C和C++运行库
VC++完美的支持C和C++标准,因此也就按照C和C++标准定义的函数原型实现了上述运行时库。为了方便有不同需求的客户使用,VC++分别实现了动态链接库DLL版本和静态链接库LIB版本。同时为了支持程序调试且不影响程序的性能,又分别提供了对应的调试版本。调试版本的名称在Release版本名称后添加了字母d。
对于C运行时库CRT,VC6.0、VC2005、VC2008和VC2010均提供了DLL版本和LIB版本。
上述各个编译器提供的LIB版的CRT库,均实现在libcmt.lib。对应的调试版名称为libcmtd.lib。
而DLL版本名称根据编译器不同而不同,我们可以从名称上加以分辨。
VC6.使用的CRT库的DLL版本在MSVCRT.DLL中实现, 对应调试版本为MSVCRTD.LIB。
VC2005使用的CRT库的DLL版本在MSVCR80.DLL中实现,对应调试版本为MSVCR80.DLL。
VC2008使用的CRT库的DLL版本在MSVCR90.DLL中实现,对应调试版本为MSVCR90D.DLL。
VC2010使用的CRT库的DLL版本在MSVCR100.DLL中实现,对应调试版本为MSVCR100D.DLL。
VC2013使用的CRT库的DLL版本在MSVCR120.DLL中实现,对应调试版本为MSVCR120D.DLL。
对于C++标准库中的IO流和STL,VC6.0、VC2005、VC2008和VC2010也提供了DLL版本和LIB版本。
LIB版均实现在libcpmt.lib中,对应的调试版本为libcpmtd.lib。
不同版本的编译器实现的DLL也不相同。
VC6.使用的C++类库的 DLL版本在MSVCP60.DLL中实现, 对应调试版本为MSVCP60D.LIB。
VC2005使用的C++类库的DLL版本在MSVCP80.DLL中实现,对应调试版本为MSVCP80.DLL。
VC2008使用的C++类库的 DLL版本在MSVCP90.DLL中实现,对应调试版本为MSVCP90D.DLL。
VC2010使用的C++类库的DLL版本在MSVCP100.DLL中实现,对应调试版本为MSVCP100D.DLL。
动态版(DLL)和静态版(LIB)C和C++运行库的优缺点
因为静态版必须把C和C++运行库复制到目标程序中(.exe),所以产生的可执行文件会比较大。同时对于使用多个模块的大型软件来说,如果每个模块均选择静态链接C或C++运行库,在程序运行时就会存在多个运行库。在链接时也会出现重复定义的问题,如图所示。
使用DLL版的C和C++运行库,程序在运行时动态的加载对应的DLL。程序体积变小,但一个很大的问题就是一旦找不到对应DLL,程序将无法运行(比如所要移植的电脑没有安装VC++)。假设使用VC6.0并选择使用MD选项构建,那么当用户使用VC2005来使用这个DLL时很可能出现找不到MSVCRT.DLL或MSVCP60.DLL的情况。