準(zhǔn)庫(kù),編譯器的關(guān)系)
引言在第一篇博客中深入淺出之STL源碼分析1_vector基本操作-CSDN博客我們將引出下面的幾個(gè)問題1.剛才我提到了我的編譯器版本是g 11.4.0而我們要講解的是STL標(biāo)準(zhǔn)模板庫(kù)那么二者之間的關(guān)系是什么以及標(biāo)準(zhǔn)庫(kù)和標(biāo)準(zhǔn)模版庫(kù)之間的關(guān)系又是什么STL安裝后我們到哪里去看源碼2.我們引入了頭文件#includevector這里的vector的內(nèi)容是什么3.vectorint test_vector; 這中定義方式是干什么的作用是什么4.test_vector.push_back(22); 對(duì)于stl源碼底層到底做了什么把對(duì)應(yīng)的數(shù)據(jù)插入到了哪個(gè)地址了什么時(shí)候分配的虛擬內(nèi)存什么時(shí)候擴(kuò)容什么時(shí)候會(huì)分配物理內(nèi)存下面我們來重點(diǎn)來說明下問題1.stl和標(biāo)準(zhǔn)庫(kù)的關(guān)系標(biāo)準(zhǔn)庫(kù)的代碼都統(tǒng)一在一個(gè)命名空間stdStandard的縮寫中也就是說std命名空間下的內(nèi)容屬于C標(biāo)準(zhǔn)庫(kù)Standard Library但是并非全部屬于標(biāo)準(zhǔn)模版庫(kù)standard template library, stl)也就是標(biāo)準(zhǔn)模板庫(kù)只是標(biāo)準(zhǔn)庫(kù)的一部分。std 是 C 標(biāo)準(zhǔn)庫(kù)的所有組件所在的命名空間包含以下類別?STL標(biāo)準(zhǔn)模板庫(kù)?容器、迭代器、算法、函數(shù)對(duì)象等。?非 STL 的標(biāo)準(zhǔn)庫(kù)組件輸入輸出iostream、字符串std::string、智能指針、多線程std::thread、異常處理、類型工具type_traits等。stl的實(shí)現(xiàn)與編譯器的關(guān)系C 標(biāo)準(zhǔn)庫(kù)含 STL的源碼由 ?編譯器廠商或開源社區(qū)實(shí)現(xiàn)不同編譯器使用不同的實(shí)現(xiàn)?GCC使用 ?**libstdc**?GNU 標(biāo)準(zhǔn) C 庫(kù)源碼路徑如 /usr/include/c/版本號(hào)?Clang默認(rèn)使用 libstdc但可配置為 ?**libc**?LLVM 項(xiàng)目開發(fā)。?MSVC使用 ?Microsoft STL僅限 Windows。MinGW 是gcc的windows版本。每個(gè)實(shí)現(xiàn)的源碼結(jié)構(gòu)和優(yōu)化策略不同但均遵循 C 標(biāo)準(zhǔn)。stl源碼何時(shí)安裝到linux?libstdc包含 STL 頭文件隨同 GCC 工具鏈一起安裝但它獨(dú)立于 gcc 編譯器本體是配套的 C 標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)。 很多人會(huì)誤以為標(biāo)準(zhǔn)庫(kù)是 gcc 程序里面的代碼其實(shí)是配套組件?安裝 GCC會(huì)同時(shí)安裝其標(biāo)準(zhǔn)庫(kù)libstdc的 ?頭文件.h/.hpp?? 和 ?預(yù)編譯二進(jìn)制庫(kù).so?。?頭文件路徑如 /usr/include/c/11/vectorGCC 11.4.0 版本。?二進(jìn)制庫(kù)路徑如 /usr/lib/gcc/aarch64-linux-gnu/11/libstdc.so。一個(gè)疑問就是一般我們的stl都是頭文件的形式我們只是需要.h文件就可以使用了為什么還有一個(gè)動(dòng)態(tài)庫(kù)呢/usr/lib/gcc/aarch64-linux-gnu/11/libstdc.so哪些實(shí)現(xiàn)需要放在.cpp中并且形成動(dòng)態(tài)庫(kù)呢雖然 STL 的模板代碼如 vector、deque?完全在頭文件中實(shí)現(xiàn)但標(biāo)準(zhǔn)庫(kù)中還有以下內(nèi)容需要編譯為二進(jìn)制庫(kù)?類別??示例??**為什么需要二進(jìn)制庫(kù)**??運(yùn)行時(shí)支持?std::exception、std::type_info需要全局唯一的 RTTI運(yùn)行時(shí)類型信息和異常處理機(jī)制。?動(dòng)態(tài)內(nèi)存管理?operator new、operator delete全局內(nèi)存分配器的實(shí)現(xiàn)需要跨編譯單元共享。?輸入輸出流?std::cout、std::fstream底層文件操作和緩沖區(qū)管理需要與操作系統(tǒng)交互無法完全用頭文件實(shí)現(xiàn)。?多線程支持?std::thread、std::mutex依賴操作系統(tǒng)原生線程 API如 pthread需封裝為二進(jìn)制接口。?數(shù)學(xué)函數(shù)?std::sin、std::sqrt某些數(shù)學(xué)函數(shù)需要鏈接到系統(tǒng)數(shù)學(xué)庫(kù)如libm。?C 標(biāo)準(zhǔn)庫(kù)兼容層?std::printf、std::mallocC 標(biāo)準(zhǔn)庫(kù)函數(shù)如printf的實(shí)現(xiàn)需要預(yù)編譯。標(biāo)準(zhǔn)庫(kù)源碼和 glibc 的區(qū)別和關(guān)系1. libstdc 和 glibc 的區(qū)別??這是兩個(gè)完全不同的庫(kù)????libstdc.so??這是 ??GNU C 標(biāo)準(zhǔn)庫(kù)??包含 C 標(biāo)準(zhǔn)庫(kù)的實(shí)現(xiàn)如std::vector,std::string,iostream等glibc??這是 ??GNU C 標(biāo)準(zhǔn)庫(kù)??包含 C 標(biāo)準(zhǔn)庫(kù)的實(shí)現(xiàn)如printf,malloc,strlen等??關(guān)系??你的程序通常會(huì)同時(shí)鏈接這兩個(gè)庫(kù)C 程序會(huì)使用 libstdc而 libstdc 內(nèi)部可能會(huì)調(diào)用 glibc 的函數(shù)2. 下載 libstdc 源碼可以從官網(wǎng)下載源碼# 下載 GCC 11.x.x 完整源碼 wget https://ftp.gnu.org/gnu/gcc/gcc-11.4.0/gcc-11.4.0.tar.xz3.源碼的目錄結(jié)構(gòu)gcc-11.4.0/├── libstdc-v3/│ ├── include/ # 標(biāo)準(zhǔn)頭文件如 vector, string 的定義│ ├── src/ # 實(shí)現(xiàn)文件│ ├── libsupc/ # 支持代碼異常處理、RTTI等│ └── testsuite/ # 測(cè)試用例├── libgcc/ # GCC 運(yùn)行時(shí)庫(kù)└── gcc/ # GCC 編譯器本身這里有c編譯器gcc,也有c編譯器g4.GCC、g 和 libstdc 的關(guān)系GCC (GNU Compiler Collection)全稱??GNU Compiler Collection本質(zhì)??不是一個(gè)單一程序而是一個(gè)??編譯器套件包含組件??C 編譯器 (gcc)C 編譯器 (g),還有其他程序的編譯器。一般小寫的gcc我們理解成c編譯器大寫的GCC 就是編譯器套件。g 的本質(zhì)定位??GCC 套件中的 C 前端實(shí)現(xiàn)方式??在大多數(shù)系統(tǒng)中g(shù)實(shí)際上是一個(gè)指向gcc的符號(hào)鏈接當(dāng)以g名稱調(diào)用時(shí)gcc會(huì)自動(dòng)添加 C 特定的編譯選項(xiàng)主要區(qū)別默認(rèn)鏈接 C 標(biāo)準(zhǔn)庫(kù) (libstdc)默認(rèn)使用 C 語法規(guī)則自動(dòng)識(shí)別.cpp等 C 文件擴(kuò)展名g,libstdc都是GCC的組成部分。5.GNU 項(xiàng)目都包括哪些東西GNU項(xiàng)目GNUs Not Unix ├─ GCCGNU Compiler Collection │ ├─ gcc/g 編譯器前端 │ ├─ libgcc 【編譯器底層運(yùn)行支持庫(kù)】 │ └─ libstdc-v3C標(biāo)準(zhǔn)庫(kù)源碼 ├─ binutils │ └─ /usr/bin/ld as ar readelf ... ├─ glibcGNU C標(biāo)準(zhǔn)庫(kù)獨(dú)立項(xiàng)目 │ ├─ shturl. │ ├─ libdl.so-ldl │ └─ ld-linux.so └─ 其他GNU工具6.-ldl、ld、ld-linux.so關(guān)系總結(jié)ld/usr/bin/ld歸屬binutilsGNU 二進(jìn)制工具集編譯期鏈接器。 作用g/gcc 編譯完成生成.o目標(biāo)文件后gcc 驅(qū)動(dòng)調(diào)用ld完成鏈接解析-lxxx參數(shù)記錄可執(zhí)行文件對(duì)共享庫(kù)的依賴。-ldl是傳給ld的鏈接參數(shù)含義鏈接libdl.so庫(kù)libdl.so屬于glibc提供dlopen/dlsym等運(yùn)行時(shí)手動(dòng)加載動(dòng)態(tài)庫(kù)的 API。注意不是鏈接器是一個(gè)庫(kù)。ld-linux.so如 ld-linux-x86-64.so.2歸屬glibcGNU C 標(biāo)準(zhǔn)庫(kù)運(yùn)行時(shí)動(dòng)態(tài)鏈接器。 作用程序啟動(dòng)后由內(nèi)核喚起讀取可執(zhí)行文件中記錄的庫(kù)依賴查詢ld.so.cache自動(dòng)加載.solibstdc.so、shturl.、libdl.so 等。一句話串起來 編譯時(shí)ldbinutils收到-ldl標(biāo)記程序依賴libdl.so程序運(yùn)行時(shí)ld-linux.soglibc負(fù)責(zé)加載libdl.so。