色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

四個(gè)方面全面解析Linux 下 C++ 編譯&鏈接

開關(guān)電源芯片 ? 來(lái)源:華為云開發(fā)者社區(qū) ? 作者:華為云開發(fā)者社區(qū) ? 2021-08-27 09:36 ? 次閱讀

【導(dǎo)讀】:編譯與鏈接對(duì)C&C++程序員既熟悉又陌生,熟悉在于每份代碼都要經(jīng)歷編譯與鏈接過(guò)程,陌生在于大部分人并不會(huì)刻意關(guān)注編譯與鏈接的原理。本文通過(guò)開發(fā)過(guò)程中碰到的四個(gè)典型問(wèn)題來(lái)探索64位linux下C++編譯&鏈接的那些事。

以下是正文

編譯原理

將如下最簡(jiǎn)單的C++程序(main.cpp)編譯成可執(zhí)行目標(biāo)程序,實(shí)際上可以分為四個(gè)步驟:預(yù)處理、編譯、匯編、鏈接,可以通過(guò)

g++ main.cpp –v看到詳細(xì)的過(guò)程,不過(guò)現(xiàn)在編譯器已經(jīng)把預(yù)處理和編譯過(guò)程合并。

預(yù)處理:g++ -E main.cpp -o main.ii,-E表示只進(jìn)行預(yù)處理。預(yù)處理主要是處理各種宏展開;添加行號(hào)和文件標(biāo)識(shí)符,為編譯器產(chǎn)生調(diào)試信息提供便利;刪除注釋;保留編譯器用到的編譯器指令等。

編譯:g++ -S main.ii –o main.s,-S表示只編譯。編譯是在預(yù)處理文件基礎(chǔ)上經(jīng)過(guò)一系列詞法分析、語(yǔ)法分析及優(yōu)化后生成匯編代碼。

匯編:g++ -c main.s –o main.o。匯編是將匯編代碼轉(zhuǎn)化為機(jī)器可以執(zhí)行的指令。

鏈接:g++ main.o。鏈接生成可執(zhí)行程序,之所以需要鏈接是因?yàn)槲覀兇a不可能像main.cpp這么簡(jiǎn)單,現(xiàn)代軟件動(dòng)則成百上千萬(wàn)行,如果寫在一個(gè)main.cpp既不利于分工合作,也無(wú)法維護(hù),因此通常是由一堆cpp文件組成,編譯器分別編譯每個(gè)cpp,這些cpp里會(huì)引用別的模塊中的函數(shù)或全局變量,在編譯單個(gè)cpp的時(shí)候是沒法知道它們的準(zhǔn)確地址,因此在編譯結(jié)束后,需要鏈接器將各種還沒有準(zhǔn)確地址的符號(hào)(函數(shù)、變量等)設(shè)置為正確的值,這樣組裝在一起就可以形成一個(gè)完整的可執(zhí)行程序。

問(wèn)題一:頭文件遮擋

在編譯過(guò)程中最詭異的問(wèn)題莫過(guò)于頭文件遮擋,如下代碼中main.cpp包含頭文件common.h,真正想用的頭文件是圖中最右邊那個(gè)包含name

c984c19a-f62b-11eb-9bcf-12bb97331649.png

成員的文件(所在目錄為。/include),但在編譯過(guò)程中中間的common.h(所在目錄為。/include1)搶先被發(fā)現(xiàn),導(dǎo)致編譯器報(bào)錯(cuò):Test結(jié)構(gòu)沒有name成員,對(duì)程序員來(lái)講,自己明明定義了name成員,居然說(shuō)沒有name這個(gè)成員,如果第一次碰到這種情況可能會(huì)懷疑人生。應(yīng)對(duì)這種詭異的問(wèn)題,我們可以用-E參數(shù)看下編譯器預(yù)處理后的輸出,如下圖。

c9b0d500-f62b-11eb-9bcf-12bb97331649.jpg

預(yù)處理文件格式如下:# linenum filename flag,表示之后的內(nèi)容是從文件名為filaname的文件中第linenum行展開的,flag的取值可以是1,2,3,4,可以是用空格分開的多值,1表示接下來(lái)要展開一個(gè)新文件;2表示一個(gè)文件展開完畢;3表示接下來(lái)內(nèi)容來(lái)自一個(gè)系統(tǒng)頭文件;4表示接下來(lái)的內(nèi)容應(yīng)該看做是extern C形式引入的。

從展開后的輸出我們可以清楚地看到Test結(jié)構(gòu)確實(shí)沒有定義name這個(gè)成員,并且Test這個(gè)結(jié)構(gòu)是在。/include1中的common.h中定義的,到此真相大白,編譯器壓根就沒用我們定義的Test結(jié)構(gòu),而是被別的同名頭文件截胡了。我們可以通過(guò)調(diào)整-I或者在頭文件中帶上部分路徑更詳細(xì)制定頭文件位置來(lái)解決。

目標(biāo)文件:

編譯鏈接最終會(huì)生成各種目標(biāo)文件,Linux下目標(biāo)文件格式為ELF(Executable Linkable Format),詳細(xì)定義見/usr/include/elf.h頭文件,常見的目標(biāo)文件有:可重定位目標(biāo)文件,也即.o結(jié)尾的目標(biāo)文件,當(dāng)然靜態(tài)庫(kù)也歸為此類;可執(zhí)行文件,比如默認(rèn)編譯出的a.out文件;共享目標(biāo)文件.so;核心轉(zhuǎn)儲(chǔ)文件,也就是core dump后產(chǎn)出的文件。Linux文件格式可以通過(guò)file命令查看。

一個(gè)典型的ELF文件格式如下圖所示,文件有兩種視角:編譯視角,以section頭部表為核心組織程序;運(yùn)行視角,程序頭部表以segment為核心組織程序。這么做主要是為了節(jié)約存儲(chǔ),很多細(xì)碎的section在運(yùn)行時(shí)由于對(duì)齊要求會(huì)導(dǎo)致很大的內(nèi)存浪費(fèi),運(yùn)行時(shí)通常會(huì)將權(quán)限類似的section組織成segment一起加載。

通過(guò)命令objdump和readelf可以查看ELF文件的內(nèi)容。

對(duì)可重定位目標(biāo)文件常見的section有:

ca2e1600-f62b-11eb-9bcf-12bb97331649.png

符號(hào)解析:

鏈接器會(huì)為對(duì)外部符號(hào)的引用修改為正確的被引用符號(hào)的地址,當(dāng)無(wú)法為引用的外部符號(hào)找到對(duì)應(yīng)的定義時(shí),鏈接器會(huì)報(bào)undefined reference to XXXX的錯(cuò)誤。另外一種情況是,找到了多個(gè)符號(hào)的定義,這種情況鏈接器有一套規(guī)則。在描述規(guī)則前需要了解強(qiáng)符號(hào)和弱符號(hào)的概念,簡(jiǎn)單講函數(shù)和已初始化的全局變量是強(qiáng)符號(hào),未初始化的全局變量是弱符號(hào)。

針對(duì)符號(hào)的多重定義鏈接器處理規(guī)則如下(作者在gcc 7.3.0上貌似規(guī)則2,3都按1處理):

1. 不允許多個(gè)強(qiáng)符號(hào)定義,鏈接器會(huì)報(bào)告重復(fù)定義貌似的錯(cuò)誤

2. 如果一個(gè)強(qiáng)符號(hào)和多個(gè)弱符號(hào)同名,則選擇強(qiáng)符號(hào)

3. 如果符號(hào)在所有目標(biāo)文件中都為弱符號(hào),那么選擇占用空間最大的一個(gè)

有了這些基礎(chǔ),我們先來(lái)看一下靜態(tài)鏈接過(guò)程:

1. 鏈接器從左到右按照命令行出現(xiàn)順序掃描目標(biāo)文件和靜態(tài)庫(kù)

2. 鏈接器維護(hù)一個(gè)目標(biāo)文件的集合E,一個(gè)未解析符號(hào)集合U,以及E中已定義的符號(hào)集合D,初始狀態(tài)E、U、D都為空

3. 對(duì)命令行上每個(gè)文件f,鏈接器會(huì)判斷f是否是一個(gè)目標(biāo)文件還是靜態(tài)庫(kù),如果是目標(biāo)文件,則f加入到E,f中未定義的符號(hào)加入到U中,已定義符號(hào)加入到D中,繼續(xù)下一文件

4. 如果是靜態(tài)庫(kù),鏈接器嘗試到靜態(tài)庫(kù)目標(biāo)文件中匹配U中未定義的符號(hào),如果m中匹配U中的一個(gè)符號(hào),那么m就和上步中文件f一樣處理,對(duì)每個(gè)成員文件都依次處理,直到U、D無(wú)變化,不包含在E中的成員文件簡(jiǎn)單丟棄

5. 所有輸入文件處理完后,如果U中還有符號(hào),則出錯(cuò),否則鏈接正常,輸出可執(zhí)行文件

問(wèn)題二:靜態(tài)庫(kù)順序

如下圖所示,main.cpp依賴liba.a,liba.a又依賴libb.a,根據(jù)靜態(tài)鏈接算法,如果用g++ main.cpp liba.a libb.a的順序能正常鏈接,因?yàn)榻馕鰈iba.a時(shí)未定義符號(hào)FunB會(huì)加入到上述算法的U中,然后在libb.a中找到定義。

如果用g++ main.cpp libb.a liba.a的順序編譯,則無(wú)法找到FunB的定義,因?yàn)楦鶕?jù)靜態(tài)鏈接算法,在解析libb.a的時(shí)候U為空,所以不需要做任何解析,簡(jiǎn)單拋棄libb.a,但在解析liba.a的時(shí)候又發(fā)現(xiàn)FunB沒有定義,導(dǎo)致U最終不為空,鏈接錯(cuò)誤。

因此在做靜態(tài)鏈接時(shí),需要特別注意庫(kù)的順序安排,引用別的庫(kù)的靜態(tài)庫(kù)需要放在前面,碰到鏈接很多庫(kù)的時(shí)候,可能需要做一些庫(kù)的調(diào)整,從而使依賴關(guān)系更清晰。

ca48b7c6-f62b-11eb-9bcf-12bb97331649.png

動(dòng)態(tài)鏈接:

之前大部分內(nèi)容都是靜態(tài)鏈接相關(guān),但靜態(tài)鏈接有很多不足:不利于更新,只要有一個(gè)庫(kù)有變動(dòng),都需要重新編譯;不利于共享,每個(gè)可執(zhí)行程序都單獨(dú)保留一份,對(duì)內(nèi)存和磁盤是極大的浪費(fèi)。

要生成動(dòng)態(tài)鏈接庫(kù)需要用到參數(shù)“-shared -fPIC”表示要生成位置無(wú)關(guān)PIC(Position Independent Code)的共享目標(biāo)文件。對(duì)靜態(tài)鏈接,在生成可執(zhí)行目標(biāo)文件時(shí)整個(gè)鏈接過(guò)程就完成了,但要想實(shí)現(xiàn)動(dòng)態(tài)鏈接的效果,就需要把程序按照模塊拆分成相對(duì)獨(dú)立的部分。

在程序運(yùn)行時(shí)將他們鏈接成一個(gè)完整的程序,同時(shí)為了實(shí)現(xiàn)代碼在不同程序間共享要保證代碼是和位置無(wú)關(guān)的(因?yàn)楣蚕砟繕?biāo)文件在每個(gè)程序中被加載的虛擬地址都不一樣,要保證它不管被加載在哪都能工作),而為了實(shí)現(xiàn)位置無(wú)關(guān)又依賴一個(gè)前提:數(shù)據(jù)段和代碼段的距離總是保持不變。

由于不管在內(nèi)存中如何加載一個(gè)目標(biāo)模塊,數(shù)據(jù)段和代碼段間的距離是不變的,編譯器在數(shù)據(jù)段前面引入了一個(gè)全局偏移表GOT(Global Offset Table),被引用的全局變量或者函數(shù)在GOT中都有一條記錄,同時(shí)編譯器為GOT中每個(gè)條目生成一個(gè)重定位記錄,因?yàn)閿?shù)據(jù)段是可以修改的,動(dòng)態(tài)鏈接器在加載時(shí)會(huì)重定位GOT中的每個(gè)條目,這樣就實(shí)現(xiàn)了PIC。

大體原理基本就這樣,但具體實(shí)現(xiàn)時(shí),對(duì)函數(shù)的處理和全局變量有所不同。由于大型程序函數(shù)成千上萬(wàn),而程序很可能只會(huì)用到其中的一小部分,因此沒必要加載的時(shí)候把所有的函數(shù)都做重定位,只有在用到的時(shí)候才對(duì)地址做修訂。

為此編譯器引入了過(guò)程鏈接表PLT(Procedure Linkage Table)來(lái)實(shí)現(xiàn)延時(shí)綁定。PLT在代碼段中,它指向了GOT中函數(shù)對(duì)應(yīng)的地址,第一次調(diào)用時(shí)候,GOT存放的不是函數(shù)的實(shí)際地址,而是PLT跳轉(zhuǎn)到GOT代碼的后一條指令地址。

這樣第一次通過(guò)PLT跳轉(zhuǎn)到GOT,然后通過(guò)GOT又調(diào)回到PLT的下一條指令,相當(dāng)于什么也沒做,緊接著PLT后面的代碼會(huì)將動(dòng)態(tài)鏈接需要的參數(shù)入棧,然后調(diào)用動(dòng)態(tài)鏈接器修正GOT中的地址,從這以后,PLT中代碼跳轉(zhuǎn)到GOT的地址就是函數(shù)真正的地址,從而實(shí)現(xiàn)了所謂的延時(shí)綁定。

對(duì)共享目標(biāo)文件而言,有幾個(gè)需要關(guān)注的section:

ca5aa10c-f62b-11eb-9bcf-12bb97331649.png

有了以上基礎(chǔ)后,我們看一下動(dòng)態(tài)鏈接的過(guò)程:

1. 裝載過(guò)程中程序執(zhí)行會(huì)跳轉(zhuǎn)到動(dòng)態(tài)鏈接器

2. 動(dòng)態(tài)鏈接器自舉通過(guò)GOT、.dynamic信息完成自身的重定位工作

3. 裝載共享目標(biāo)文件:將可執(zhí)行文件和鏈接器本身符號(hào)合并入全局符號(hào)表,依次廣度優(yōu)先遍歷共享目標(biāo)文件,它們的符號(hào)表會(huì)不斷合并到全局符號(hào)表中,如果多個(gè)共享對(duì)象有相同的符號(hào),則優(yōu)先載入的共享目標(biāo)文件會(huì)屏蔽掉后面的符號(hào)

4. 重定位和初始化

問(wèn)題三:全局符號(hào)介入

動(dòng)態(tài)鏈接過(guò)程中最關(guān)鍵的第3步可以看到,當(dāng)多個(gè)共享目標(biāo)文件中包含一個(gè)相同的符號(hào),那么會(huì)導(dǎo)致先被加載的符號(hào)占住全局符號(hào)表,后續(xù)共享目標(biāo)文件中相同符號(hào)被忽略。當(dāng)我們代碼中沒有很好的處理命名的話,會(huì)導(dǎo)致非常奇怪的錯(cuò)誤,幸運(yùn)的話立刻core dump,不幸的話直到程序運(yùn)行很久以后才莫名其妙的core dump,甚至永遠(yuǎn)不會(huì)core dump但是結(jié)果不正確。

如下圖所示,main.cpp中會(huì)用到兩個(gè)動(dòng)態(tài)庫(kù)libadd.so,libadd1.so的符號(hào),我們把重點(diǎn)

ca741d12-f62b-11eb-9bcf-12bb97331649.png

放在Add函數(shù)的處理上,當(dāng)我們以g++ main.cpp libadd.so libadd1.so編譯時(shí),程序輸出“Add in add lib”說(shuō)明Add是用的libadd.so中的符號(hào)(add.cpp),當(dāng)我們以g++ main.cpp libadd1.so libadd.so編譯時(shí)。

程序輸出“Add in add1 lib”說(shuō)明Add是用的libadd1.so中的符號(hào),這時(shí)候問(wèn)題就大了,調(diào)用方main.cpp中認(rèn)為Add只有兩個(gè)參數(shù),而add1.cpp中認(rèn)為Add有三個(gè)參數(shù),程序中如果有這樣的代碼,可以預(yù)見很可能造成巨大的混亂。

具體符號(hào)解析我們可以通過(guò)LD_DEBUG=all 。/a.out來(lái)觀察Add的解析過(guò)程,如下圖所示:左邊是對(duì)應(yīng)libadd.so在編譯時(shí)放在前面的情況,Add綁定在libadd.so中,右邊對(duì)應(yīng)libadd1.so放前面的情況,Add綁定在libadd1.so中。

caa41b20-f62b-11eb-9bcf-12bb97331649.png

運(yùn)行時(shí)加載動(dòng)態(tài)庫(kù):

有了動(dòng)態(tài)鏈接和共享目標(biāo)文件的加持,Linux提供了一種更加靈活的模塊加載方式:通過(guò)提供dlopen,dlsym,dlclose,dlerror幾個(gè)API,可以實(shí)現(xiàn)在運(yùn)行的時(shí)候動(dòng)態(tài)加載模塊,從而實(shí)現(xiàn)插件的功能。

如下代碼演示了動(dòng)態(tài)加載Add函數(shù)的過(guò)程,add.cpp按照正常編譯“g++ -fPIC –shared –o libadd.so add.cpp”成libadd.so,main.cpp通過(guò)“g++ main.cpp -ldl”編譯為a.out。main.cpp中首先通過(guò)dlopen接口取得一個(gè)句柄void *handle。

然后通過(guò)dlsym從句柄中查找符號(hào)Add,找到后將其轉(zhuǎn)化為Add函數(shù),然后就可以按照正常的函數(shù)使用,最后dlclose關(guān)閉句柄,期間有任何錯(cuò)誤可以通過(guò)dlerror來(lái)獲取。

caef8b32-f62b-11eb-9bcf-12bb97331649.jpg

問(wèn)題四:靜態(tài)全局變量與動(dòng)態(tài)庫(kù)導(dǎo)致double free

在全面了解了動(dòng)態(tài)鏈接相關(guān)知識(shí)后,我們來(lái)看一個(gè)靜態(tài)全局變量和動(dòng)態(tài)庫(kù)糾結(jié)在一起引發(fā)的問(wèn)題,代碼如下,foo.cpp中有一個(gè)靜態(tài)全局對(duì)象foo_,foo.cpp會(huì)編譯成一個(gè)libfoo.a,bar.cpp依賴libfoo.a庫(kù),它本身會(huì)編譯成libbar.so,main.cpp既依賴于libfoo.a又依賴libbar.so。

caf98eac-f62b-11eb-9bcf-12bb97331649.jpg

編譯的makefile如下:

cb1d0724-f62b-11eb-9bcf-12bb97331649.png

運(yùn)行a.out會(huì)導(dǎo)致double free的錯(cuò)誤。這是由于在一個(gè)位置上調(diào)用了兩次析構(gòu)函數(shù)造成的。之所以會(huì)這樣是因?yàn)殒溄拥臅r(shí)候先鏈接的靜態(tài)庫(kù),將foo_的符號(hào)解析為靜態(tài)庫(kù)中的全局變量,當(dāng)動(dòng)態(tài)鏈接libbar.so時(shí),由于全局已經(jīng)有符號(hào)foo_,因此根據(jù)全局符號(hào)介入,動(dòng)態(tài)庫(kù)中對(duì)foo_的引用會(huì)指向靜態(tài)庫(kù)中版本,導(dǎo)致最后在同一個(gè)對(duì)象上析構(gòu)了兩次。

cb2b9a28-f62b-11eb-9bcf-12bb97331649.png

解決辦法如下:

1. 不使用全局對(duì)象

2. 編譯時(shí)候調(diào)換庫(kù)的順序,動(dòng)態(tài)庫(kù)放在前面,這樣全局只會(huì)有一個(gè)foo_對(duì)象

3. 全部使用動(dòng)態(tài)庫(kù)

4. 通過(guò)編譯器參數(shù)來(lái)控制符號(hào)的可見性。

總結(jié):

通過(guò)四個(gè)編譯鏈接中碰到的問(wèn)題,基本把編譯鏈接的這些事覆蓋了一遍,有了這些基礎(chǔ),在日常工作中應(yīng)對(duì)一般的編譯鏈接問(wèn)題應(yīng)該可以做到游刃有余。由于篇幅有限,文章省略了大量的細(xì)節(jié),主要集中在大的框架原理性梳理,如果想進(jìn)一步深挖相關(guān)的細(xì)節(jié),可參與相關(guān)參考文獻(xiàn),以及閱讀elf.h相關(guān)的頭文件。

轉(zhuǎn)自:https://my.oschina.net/u/4526289/blog/4651990

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • PIC
    PIC
    +關(guān)注

    關(guān)注

    8

    文章

    507

    瀏覽量

    87727
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4345

    瀏覽量

    62870
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4823

    瀏覽量

    68894
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1642

    瀏覽量

    49238
  • got
    got
    +關(guān)注

    關(guān)注

    0

    文章

    11

    瀏覽量

    3782

原文標(biāo)題:從四個(gè)問(wèn)題透析 Linux 下 C++ 編譯&鏈接

文章出處:【微信號(hào):gh_3980db2283cd,微信公眾號(hào):開關(guān)電源芯片】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    C語(yǔ)言的編譯鏈接過(guò)程

    ? C語(yǔ)言的編譯鏈接過(guò)程要把我們編寫的一個(gè)C程序源代碼轉(zhuǎn)換成可以在硬件上運(yùn)行的程序(可執(zhí)行代碼),需要進(jìn)行
    的頭像 發(fā)表于 08-21 10:06 ?2671次閱讀
    <b class='flag-5'>C</b>語(yǔ)言的<b class='flag-5'>編譯</b><b class='flag-5'>鏈接</b>過(guò)程

    Linux GCC的編譯

    一、Linux 多文件編譯 在上一篇 Linux C 編程我們知道了
    的頭像 發(fā)表于 09-11 15:18 ?2690次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>下</b>GCC的<b class='flag-5'>編譯</b>

    c++編譯鏈接失敗的原因?如何解決?

    /c++項(xiàng)目,將剛才新建的項(xiàng)目轉(zhuǎn)換為c++項(xiàng)目。 完成后點(diǎn)擊編譯,此時(shí)也是正常的。 新建一個(gè)cpp文件,將原項(xiàng)目的main.c中內(nèi)容全部拷貝
    發(fā)表于 07-25 08:13

    C/C++中的整型常識(shí)

    C/C++中的整型常識(shí)很多人對(duì)C/C++中的整型不太了解,導(dǎo)致代碼移植的時(shí)候出現(xiàn)問(wèn)題,本人在此總結(jié)一,若有描述錯(cuò)誤,請(qǐng)務(wù)必指出,謝謝! &
    發(fā)表于 10-07 11:12

    程序的鏈接和裝入及Linux動(dòng)態(tài)鏈接的實(shí)現(xiàn)

    之后最終的可執(zhí)行程序就生成了。 可執(zhí)行程序生成后,下一步就是將其裝入內(nèi)存運(yùn)行。Linux編譯器(C語(yǔ)言)是cc1,匯編器是as,鏈接器是
    發(fā)表于 09-13 11:18

    高質(zhì)量C&;amp;C++

    高質(zhì)量C&;amp;C++
    發(fā)表于 08-16 19:45

    Linux系統(tǒng)鏈接原理是什么?有哪些應(yīng)用呢

    顯而易見的,就是可執(zhí)行文件可能會(huì)變得很臃腫。靜態(tài)庫(kù)的創(chuàng)建本文以則運(yùn)算來(lái)創(chuàng)建一個(gè)靜態(tài)庫(kù),該靜態(tài)庫(kù)中包含四個(gè)函數(shù):加、減、乘、除。生成一個(gè)可重定位的目標(biāo)文件。在
    發(fā)表于 06-21 17:05

    LinuxC/C++編譯器gcc使用指南

    1.gcc包含的c/c++編譯器 gcc,cc與c++,g++ gcc和cc是一樣的,c++和g++是一樣的。一般
    發(fā)表于 11-02 10:59 ?0次下載

    高級(jí)C/C++編譯技術(shù)

    C/C++編譯技術(shù)
    發(fā)表于 12-04 17:19 ?18次下載

    了解“預(yù)編譯編譯、匯編、鏈接”這四個(gè)過(guò)程對(duì)你有很大幫助

    C語(yǔ)言的編譯鏈接過(guò)程要把我們編寫的一個(gè)c程序(源代碼)轉(zhuǎn)換成可以在硬件上運(yùn)行的程序(可執(zhí)行代碼),需要進(jìn)行
    的頭像 發(fā)表于 04-18 10:08 ?3.6w次閱讀
    了解“預(yù)<b class='flag-5'>編譯</b>、<b class='flag-5'>編譯</b>、匯編、<b class='flag-5'>鏈接</b>”這<b class='flag-5'>四個(gè)</b>過(guò)程對(duì)你有很大幫助

    linux嵌入式主要學(xué)什么,學(xué)嵌入式linux,用什么開發(fā)板,請(qǐng)大家推薦一

    基礎(chǔ)、數(shù)據(jù)結(jié)構(gòu)、電子電路)第一天上數(shù)電&amp;C語(yǔ)言基礎(chǔ)測(cè)試第一天C++語(yǔ)言&amp;操作系統(tǒng)基礎(chǔ)測(cè)試第二天上操作系統(tǒng)基礎(chǔ)第二天
    發(fā)表于 11-02 14:51 ?17次下載
    <b class='flag-5'>linux</b>嵌入式主要學(xué)什么,學(xué)嵌入式<b class='flag-5'>linux</b>,用什么開發(fā)板,請(qǐng)大家推薦一<b class='flag-5'>下</b>

    存儲(chǔ)類&amp;作用域&amp;生命周期&amp;鏈接屬性

    目錄前言一、存儲(chǔ)類&amp;amp;作用域&amp;amp;生命周期&amp;amp;
    發(fā)表于 12-09 15:51 ?5次下載
    存儲(chǔ)類&<b class='flag-5'>amp</b>;作用域&<b class='flag-5'>amp</b>;生命周期&<b class='flag-5'>amp</b>;<b class='flag-5'>鏈接</b>屬性

    Linux系統(tǒng)C/C++編譯流程與步驟

    編譯的,即每個(gè).c文件會(huì)形成一個(gè).o文件,為了滿足前面說(shuō)的依賴關(guān)系,則需要將這些源文件產(chǎn)生的目標(biāo)文件進(jìn)行鏈接,從而形成一個(gè)可以執(zhí)行的程序。這
    的頭像 發(fā)表于 11-08 16:11 ?1467次閱讀

    探索64位linuxC++編譯&amp;amp;鏈接的那些事

    編譯鏈接對(duì)C&;C++程序員既熟悉又陌生,熟悉在于每份代碼都要經(jīng)歷編譯鏈接過(guò)程,陌生在
    的頭像 發(fā)表于 04-15 10:44 ?986次閱讀

    OK3568-C開發(fā)板_AMP_Linux4.19.232+QT5.15.8_用戶編譯手冊(cè)_V1.0

    OK3568-C_AMP_Linux4.19.232+QT5.15.8_用戶編譯手冊(cè)_V1.0_20231227
    發(fā)表于 01-23 16:28 ?12次下載
    主站蜘蛛池模板: 好男人好资源在线播放 | 色视频色露露永久免费观看 | 日本黄色网站在线观看 | 亚洲熟少妇在线播放999 | 俄罗斯搜索引擎Yandex推广入口 | 羞羞影院午夜男女爽爽影院网站 | 国产产乱码一二三区别免费 | 亚洲性爱城 | 泡妞高手在都市免费观看 | 97SE亚洲国产综合自在线不卡 | 久久在精品线影院精品国产 | 伊人久久丁香色婷婷啪啪 | 性春院| 2021乱码精品公司 | 魔乳 堕乳漫画acg产卵 | 在线成 人av影院 | 久久精品中文字幕免费 | 午夜影视免费 | 亚洲一级电影 | 日本夜夜夜| 亚洲国产成人精品青青草原100 | 国产亚洲精品久久播放 | 999久久久国产 | 各种肉黄浪荡故事集 | 久久视频这里只精品99热在线 | 久久偷拍vs国产在线播放 | 俄罗斯乌克兰战争原因 | 美女快播第一网 | 老师洗澡让我吃她胸的视频 | 某上海少妇3P黑人完整版BD | 精品无码久久久久久久久 | 亚洲成人免费 | 在线观看免费小视频 | 97精品一区二区视频在线观看 | 欧美黄色第一页 | 国产精品久久久久久人妻香蕉 | www.97干| 高挑人妻无奈张开腿 | 男女啪啪抽搐呻吟高潮动态图 | 亚洲爱视频 | 国产精品久久久久影院免费 |