青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Impossible is nothing  
  愛過知情重醉過知酒濃   花開花謝終是空   緣份不停留像春風(fēng)來又走   女人如花花似夢
公告
日歷
<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456
統(tǒng)計
  • 隨筆 - 8
  • 文章 - 91
  • 評論 - 16
  • 引用 - 0

導(dǎo)航

常用鏈接

留言簿(4)

隨筆分類(4)

隨筆檔案(8)

文章分類(77)

文章檔案(91)

相冊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

 

首先,C++標(biāo)準(zhǔn)中提到,一個編譯單元[translation unit]是指一個.cpp文件以及它所include的所有.h文件,.h文件里的代碼將會被擴展到包含它的.cpp文件里,然后編譯器編譯該.cpp文件為一個.obj文件,后者擁有PE[Portable Executable,windows可執(zhí)行文件]文件格式,并且本身包含的就已經(jīng)是二進制碼,但是,不一定能夠執(zhí)行,因為并不保證其中一定有main函數(shù)。當(dāng)編譯器將一個工程里的所有.cpp文件以分離的方式編譯完畢后,再由連接器(linker)進行連接成為一個.exe文件。

舉個例子:

//---------------test.h-------------------//

    void f();//這里聲明一個函數(shù)f

//---------------test.cpp--------------//

    #include”test.h”

    void f()

    {

      …//do something

    }  //這里實現(xiàn)出test.h中聲明的f函數(shù)

//---------------main.cpp--------------//

    #include”test.h”

    int main()

    {

       f(); //調(diào)用ff具有外部連接類型

    }

在這個例子中,test. cppmain.cpp各被編譯成為不同的.obj文件[姑且命名為test.objmain.obj],在main.cpp中,調(diào)用了f函數(shù),然而當(dāng)編譯器編譯main.cpp時,它所僅僅知道的只是main.cpp中所包含的test.h文件中的一個關(guān)于void f();的聲明,所以,編譯器將這里的f看作外部連接類型,即認為它的函數(shù)實現(xiàn)代碼在另一個.obj文件中,本例也就是test.obj,也就是說,main.obj中實際沒有關(guān)于f函數(shù)的哪怕一行二進制代碼,而這些代碼實際存在于test.cpp所編譯成的test.obj中。在main.obj中對f的調(diào)用只會生成一行call指令,像這樣:

     call f [C++中這個名字當(dāng)然是經(jīng)過mangling[處理]過的]

在編譯時,這個call指令顯然是錯誤的,因為main.obj中并無一行f的實現(xiàn)代碼。那怎么辦呢?這就是連接器的任務(wù),連接器負責(zé)在其它的.obj[本例為test.obj]尋找f的實現(xiàn)代碼,找到以后將call f這個指令的調(diào)用地址換成實際的f的函數(shù)進入點地址。需要注意的是:連接器實際上將工程里的.obj“連接”成了一個.exe文件,而它最關(guān)鍵的任務(wù)就是上面說的,尋找一個外部連接符號在另一個.obj中的地址,然后替換原來的“虛假”地址。

這個過程如果說的更深入就是:

      call f這行指令其實并不是這樣的,它實際上是所謂的stub,也就是一個

      jmp 0x23423[這個地址可能是任意的,然而關(guān)鍵是這個地址上有一行指令來進行真正的call f動作。也就是說,這個.obj文件里面所有對f的調(diào)用都jmp向同一個地址,在后者那兒才真正”call”f。這樣做的好處就是連接器修改地址時只要對后者的call XXX地址作改動就行了。但是,連接器是如何找到f的實際地址的呢[在本例中這處于test.obj],因為.obj.exe的格式都是一樣的,在這樣的文件中有一個符號導(dǎo)入表和符號導(dǎo)出表[import tableexport table]其中將所有符號和它們的地址關(guān)聯(lián)起來。這樣連接器只要在test.obj的符號導(dǎo)出表中尋找符號f[當(dāng)然C++f作了mangling]的地址就行了,然后作一些偏移量處理后[因為是將兩個.obj文件合并,當(dāng)然地址會有一定的偏移,這個連接器清楚]寫入main.obj中的符號導(dǎo)入表中f所占有的那一項。

這就是大概的過程。其中關(guān)鍵就是:

    編譯main.cpp時,編譯器不知道f的實現(xiàn),所有當(dāng)碰到對它的調(diào)用時只是給出一個指示,指示連接器應(yīng)該為它尋找f的實現(xiàn)體。這也就是說main.obj中沒有關(guān)于f的任何一行二進制代碼。

    編譯test.cpp時,編譯器找到了f的實現(xiàn)。于是乎f的實現(xiàn)[二進制代碼]出現(xiàn)在test.obj里。

    連接時,連接器在test.obj中找到f的實現(xiàn)代碼[二進制]的地址[通過符號導(dǎo)出表]。然后將main.obj中懸而未決的call XXX地址改成f實際的地址。

    完成。

 

 

然而,對于模板,你知道,模板函數(shù)的代碼其實并不能直接編譯成二進制代碼,其中要有一個“具現(xiàn)化”的過程。舉個例子:

//----------main.cpp------//

 template<class T>

 void f(T t)

 {}

 int main()

 {

   …//do something

   f(10); //call f<int> 編譯器在這里決定給f一個f<int>的具現(xiàn)體

   …//do other thing

  }

也就是說,如果你在main.cpp文件中沒有調(diào)用過ff也就得不到具現(xiàn),從而main.obj中也就沒有關(guān)于f的任意一行二進制代碼!!如果你這樣調(diào)用了:

  f(10); //f<int>得以具現(xiàn)化出來

f(10.0); //f<double>得以具現(xiàn)化出來

這樣main.obj中也就有了f<int>,f<double>兩個函數(shù)的二進制代碼段。以此類推。

然而具現(xiàn)化要求編譯器知道模板的定義,不是嗎?

看下面的例子:[將模板和它的實現(xiàn)分離]

 //-------------test.h----------------//

    template<class T>

    class A

    {

     public:

        void f(); //這里只是個聲明

     };

//---------------test.cpp-------------//

  #include”test.h”

  template<class T>

  void A<T>::f()  //模板的實現(xiàn),但注意:不是具現(xiàn)

  {

    …//do something

  }

//---------------main.cpp---------------//

   #include”test.h”

   int main()

   {

      A<int> a;

a.        f(); //編譯器在這里并不知道A<int>::f的定義,因為它不在test.h里面

   //于是編譯器只好寄希望于連接器,希望它能夠在其他.obj里面找到

   //A<int>::f的實現(xiàn)體,在本例中就是test.obj,然而,后者中真有A<int>::f

   //二進制代碼嗎?NO!!!因為C++標(biāo)準(zhǔn)明確表示,當(dāng)一個模板不被用到的時

   //侯它就不該被具現(xiàn)出來,test.cpp中用到了A<int>::f了嗎?沒有!!所以實

   //際上test.cpp編譯出來的test.obj文件中關(guān)于A::f的一行二進制代碼也沒有

   //于是連接器就傻眼了,只好給出一個連接錯誤

   //但是,如果在test.cpp中寫一個函數(shù),其中調(diào)用A<int>::f,則編譯器會將其//具現(xiàn)出來,因為在這個點上[test.cpp],編譯器知道模板的定義,所以能//夠具現(xiàn)化,于是,test.obj的符號導(dǎo)出表中就有了A<int>::f這個符號的地

//址,于是連接器就能夠完成任務(wù)。

         }


        
關(guān)鍵是:在分離式編譯的環(huán)境下,編譯器編譯某一個.cpp文件時并不知道另一個.cpp文件的存在,也不會去查找[當(dāng)遇到未決符號時它會寄希望于連接器]。這種模式在沒有模板的情況下運行良好,但遇到模板時就傻眼了,因為模板僅在需要的時候才會具現(xiàn)化出來,所以,當(dāng)編譯器只看到模板的聲明時,它不能具現(xiàn)化該模板,只能創(chuàng)建一個具有外部連接的符號并期待連接器能夠?qū)⒎柕牡刂窙Q議出來。然而當(dāng)實現(xiàn)該模板的.cpp文件中沒有用到模板的具現(xiàn)體時,編譯器懶得去具現(xiàn),所以,整個工程的.obj中就找不到一行模板具現(xiàn)體的二進制代碼,于是連接器也黔驢技窮了。

posted on 2006-02-25 18:31 笑笑生 閱讀(171) 評論(0)  編輯 收藏 引用 所屬分類: C++語言
 
Copyright © 笑笑生 Powered by: 博客園 模板提供:滬江博客
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧洲精品一区| 久久激情五月激情| 最新国产成人在线观看| 欧美激情va永久在线播放| 亚洲国产精品美女| 久久美女性网| 国产精品日本欧美一区二区三区| 1000部精品久久久久久久久| 在线一区亚洲| 欧美成人有码| 久久综合色综合88| 国产一区二区三区高清| 亚洲欧洲日本国产| 国产精品久久7| 亚洲欧洲日韩女同| 免费成人高清在线视频| 久久黄色小说| 在线观看成人av电影| 久久综合久久久久88| 欧美一区二区视频在线观看| 国产日韩精品一区二区| 午夜精品福利电影| 一区二区高清视频| 国产精品av久久久久久麻豆网| 99视频有精品| 亚洲午夜高清视频| 国产精品丝袜xxxxxxx| 欧美在线看片a免费观看| 亚洲视频电影在线| 国产免费成人av| 久久天堂精品| 久热精品视频在线| 亚洲理伦在线| 在线亚洲激情| 国产一区二区三区在线观看视频| 久久久免费观看视频| 久久性天堂网| 一区二区高清视频在线观看| 宅男在线国产精品| 国产原创一区二区| 欧美福利精品| 欧美日韩在线三级| 欧美伊人久久大香线蕉综合69| 欧美一区二区三区四区在线观看| 在线看视频不卡| 亚洲美女在线看| 国产亚洲毛片在线| 亚洲国产第一| 国产欧美 在线欧美| 女人色偷偷aa久久天堂| 欧美国产精品专区| 久久av二区| 欧美a级片网站| 亚洲欧美日韩在线| 美女黄色成人网| 亚洲影院在线| 久久夜色撩人精品| 亚洲自拍偷拍福利| 久久综合国产精品台湾中文娱乐网| 亚洲日本在线视频观看| 亚洲一区三区在线观看| 亚洲日本理论电影| 欧美一区二区三区四区视频| 一区二区三区高清视频在线观看| 亚洲欧美日韩国产综合在线| 亚洲麻豆av| 久久精品99国产精品日本| 夜夜嗨av一区二区三区网站四季av| 亚洲在线电影| 亚洲精选国产| 久久免费国产| 香蕉久久国产| 欧美精品一区二区精品网| 欧美一区在线视频| 欧美日韩亚洲高清一区二区| 麻豆av一区二区三区久久| 欧美日韩国产一区精品一区| 亚洲精品免费网站| 久久精品91| 午夜久久久久| 欧美日韩一二三区| 亚洲国产精品一区二区第四页av| 国产一区二区电影在线观看 | 亚洲国产精品成人va在线观看| 亚洲少妇中出一区| 日韩午夜激情av| 免费观看久久久4p| 久久久99精品免费观看不卡| 欧美精品www在线观看| 麻豆精品一区二区av白丝在线| 国产精品中文字幕欧美| 9l视频自拍蝌蚪9l视频成人| 最新国产乱人伦偷精品免费网站 | 国自产拍偷拍福利精品免费一| 亚洲一区二区三区久久| 亚洲免费婷婷| 国产精品久久二区| 一区二区三区免费观看| 一区二区免费看| 欧美精品一区二区精品网| 亚洲欧洲午夜| 一本久道久久综合中文字幕| 欧美国产精品专区| 亚洲美女视频网| 在线视频日韩| 欧美视频精品一区| 亚洲社区在线观看| 欧美一区二区三区另类 | 在线看国产一区| 美女精品一区| 日韩一二三区视频| 亚洲欧美日韩直播| 狠狠色狠狠色综合日日tαg| 久久久久九九九| 欧美国产精品久久| 夜夜嗨一区二区| 国产欧美日韩不卡免费| 欧美在线观看日本一区| 欧美成人自拍| 亚洲视频国产视频| 国产欧美亚洲视频| 久久一区二区三区av| 亚洲国产精品欧美一二99| 亚洲视频999| 狠狠色综合日日| 欧美韩日亚洲| 亚洲欧美综合一区| 欧美国产视频在线观看| 亚洲一区二区免费| 韩日视频一区| 欧美人与性动交cc0o| 亚洲欧美综合国产精品一区| 欧美高清在线一区二区| 午夜精品久久久久久久99水蜜桃| 黄色精品一区| 欧美日韩在线大尺度| 欧美在线日韩精品| 亚洲三级影片| 久久午夜国产精品| 中文精品视频| 久久免费视频这里只有精品| 亚洲精品中文字| 欧美在线影院在线视频| 亚洲国产天堂久久综合网| 欧美性猛交99久久久久99按摩| 久久精品青青大伊人av| 一本色道精品久久一区二区三区| 久久久久一本一区二区青青蜜月| 99视频热这里只有精品免费| 韩国精品一区二区三区| 欧美四级伦理在线| 欧美成人按摩| 久久精品成人| 午夜电影亚洲| 一区二区三区精密机械公司| 欧美黄色网络| 久久夜色精品国产噜噜av| 午夜国产不卡在线观看视频| 亚洲人成在线免费观看| 国内成+人亚洲+欧美+综合在线| 欧美私人网站| 欧美日韩国产一级| 欧美不卡视频| 久久综合给合| 久久露脸国产精品| 亚洲欧美另类中文字幕| 99视频+国产日韩欧美| 亚洲国产成人在线播放| 欧美a级在线| 久久野战av| 久久亚洲国产精品一区二区| 久久福利一区| 久久成人久久爱| 欧美一区网站| 久久成人这里只有精品| 久久精品久久综合| 欧美中日韩免费视频| 先锋影音久久久| 午夜亚洲福利在线老司机| 亚洲欧美久久久久一区二区三区| 亚洲视频一区| 亚洲综合电影一区二区三区| 亚洲一区在线免费| 亚洲欧美日韩精品在线| 亚洲影院在线观看| 欧美一级视频精品观看| 午夜精品福利在线观看| 亚洲欧美精品在线观看| 性欧美精品高清| 欧美在线播放| 久久久久久久久一区二区| 久久免费国产精品1| 久久人人爽爽爽人久久久| 久久一区二区三区国产精品| 久久亚洲精品视频| 欧美成人高清| 99精品国产高清一区二区| 正在播放亚洲| 欧美一激情一区二区三区| 欧美中文在线视频|