小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

GCC的Link行為

 心不留意外塵 2016-04-15

from http://blog.csdn.net/dreamfreelancer/article/details/4216147

編譯器:G++
OS:LINUX

 

1.link順序

GCC Link程序在.o文件列表中查找被引用實(shí)體(函數(shù)或Class)時(shí)不設(shè)定順序,即引用實(shí)體所在.o文件出現(xiàn)

在被引用實(shí)體所在的.o文件的左側(cè),或右側(cè)都能通過編譯,不會(huì)出現(xiàn)找不到引用的錯(cuò)誤
但若從.a文件列表中搜索被引用實(shí)體,情況將不同,總是則從右向左順序查找,因此,被引用實(shí)體所在.a

文件必需出現(xiàn)在引用實(shí)體所在.a文件的右側(cè),否則,將報(bào)“未定義引用(undefined reference)”錯(cuò)誤

2.重復(fù)引用的處理
若同一實(shí)體分別在兩個(gè)以上.o或.a文件中被實(shí)現(xiàn),Link時(shí)又同時(shí)指定了這些.o或.a文件,結(jié)果會(huì)怎么樣?

你可能認(rèn)為這是個(gè)常識(shí)問題:編譯器報(bào)多重定義的錯(cuò)。事實(shí)果真如此嗎?正確答案:取決于你編譯命令行

怎么寫。
若指定.o文件列表,你的常識(shí)是對(duì),編譯器報(bào)多重定義的錯(cuò)(multiple definition)。
但若指定.a文件列表,你的常識(shí)將是錯(cuò)的,編譯器并不報(bào)錯(cuò),而是引用.a文件列表中,從若向左第一次出

現(xiàn)的實(shí)現(xiàn)。
引用實(shí)體和被引用實(shí)體混合出現(xiàn)在.o, .a的文件中時(shí)情況較復(fù)雜,大體符合.o優(yōu)先的原則
引用與被引用實(shí)體分別所在的.o被打包成一個(gè).a時(shí),打包時(shí).o沒有順序依賴,但當(dāng)其中存在多重定義時(shí),

情況將不同,實(shí)際被引用的是按照打包順序,從左向右,出現(xiàn)在引用實(shí)體右側(cè)的第一個(gè)實(shí)現(xiàn)。

測(cè)試過程如下:
1.在a.h文件中定義一個(gè)函數(shù):
void f_a();

2.在a.cpp中提供一個(gè)實(shí)現(xiàn)版本
void f_a()
{
   printf("hello f_a from a.cpp/n");
}
編譯成a.o, 并ar rsuv a.a a.o成a.a

3.在b.cpp中提供void f_a()并一實(shí)現(xiàn)版本
void f_a()
{
  printf("hello f_a from b.cpp/n");
}
編譯成b.o, 并ar rsuv b.a b.o成b.a

4.在c.cpp中實(shí)現(xiàn)
void f_c()
{
  printf("f_c will call f_a.../n");
  f_a();
}
編譯成c.o, 并ar rsuv c.a c.o成c.a

5.在main.cpp中call f_c()
int main(int argc, char **argv)
{
 f_c();
 return 0;
}

6.測(cè)試Link順序
6.1 g++ -o main main.cpp a.o c.o或g++ -o main main.cpp c.o a.o將得到同樣的正確的結(jié)果--被引

用實(shí)體在.o文件列表中無順序依賴

6.2 g++ -o main main.cpp c.a a.a通過編譯,得到正確結(jié)果,但g++ -o main main.cpp a.a c.a將通不

過編譯,報(bào)錯(cuò):undefined reference to `f_a()' -- 被引用實(shí)體在.a文件列表中有順序依賴,被引用

實(shí)體必需出現(xiàn)在引用實(shí)體的左側(cè)

7.測(cè)試多重實(shí)現(xiàn)
7.1 g++ -o main main.cpp a.o b.o c.o(a.o, b.o, c.o任意排列組合),編譯將失敗,報(bào)錯(cuò):multiple

definition of `f_a()'--在.o列表中若存在多重定義,編譯將失敗

7.2 g++ -o main main.cpp a.a b.a c.a報(bào)錯(cuò):undefined reference to `f_a()'--符合上面關(guān)于Link

順序的測(cè)試; g++ -o main main.cpp c.a b.a a.a,通過編譯,實(shí)際引用b.a中的實(shí)現(xiàn); g++ -o main

main.cpp c.a a.a b.a, 通過編譯,實(shí)際引用a.a中的實(shí)現(xiàn)。

7.3 g++ -o main main.cpp cc.a a.o b.a, 通過編譯,實(shí)際引用a.o中的實(shí)現(xiàn)版本--.o中的實(shí)現(xiàn)被引用

的優(yōu)先級(jí)高于.a;g++ -o main main.cpp c.a b.a a.o, 編譯出錯(cuò),報(bào)“多重定義(multiple definition

of `f_a()')”; g++ -o main main.cpp b.a c.a a.o或g++ -o main main.cpp b.a a.o c.a,通過編譯,

實(shí)際引用a.o中的實(shí)現(xiàn)--引用實(shí)體與被引用實(shí)體有的出現(xiàn)在.a中,有的出現(xiàn)在.o中,且存多重定義的情形

是有些復(fù)雜的,實(shí)際工作中應(yīng)謹(jǐn)慎處理

7.4 將多個(gè).o打成一個(gè).a(文件名體現(xiàn)打包順序),g++ -o main main.cpp ac.a或g++ -o main main.cpp

ca.a, 通過編譯; g++ -o main main.cpp cc.o ab.a,編譯通過,實(shí)際引用a.o實(shí)現(xiàn),g++ -o main

main.cpp cc.o ba.a,編譯通過,實(shí)際引用b.o實(shí)現(xiàn); g++ -o main main.cpp abc.a,通過編譯,實(shí)際引用

a.o實(shí)現(xiàn);g++ -o main main.cpp bac.a,通過編譯,實(shí)際引用b.o實(shí)現(xiàn);g++ -o main main.cpp acb.a,通

過編譯,實(shí)際引用b.o實(shí)現(xiàn); g++ -o main main.cpp abc.a,通過編譯,實(shí)際引用a.o實(shí)現(xiàn);g++ -o main

main.cpp bac.a,通過編譯,實(shí)際引用b.o實(shí)現(xiàn)

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多