.NET程式員的C情結(二)

來源:互聯網
上載者:User

C多檔案編譯、範圍和儲存周期
  所謂的編譯,分為兩個步驟:編譯和連結
編譯有兩個過程:

  • a)先行編譯:處理#...的語句。#define的宏替換、#if條件編譯、#include只是簡單的把對應的檔案內容複寫到#include語句的位置
  • b)單元原始碼編譯:隨後編譯器對每個cpp檔案(在先行編譯階段已經將#include的檔案複製完成)單獨編譯成模組(.obj/.o等),在這個過程中除了語法檢查外,還要在本cpp檔案中檢查調用函數或引用變數是否聲明過。最後產生的模組開頭會有一個符號表,其中包括了本模組定義的函數或變數在本模組中的位移量;以及本模組引用的外部變數或函數(稱為unsolved symbol)。

連結就是將多個模組檔案連結成最後的目標程式。連結過程中需要檢查每個模組中的函式宣告或變數聲明的實際位置。比如模組A聲明了一個全域變數global其實是在模組B中定義的,那麼鏈

接器需要把模組A對global的引用地址替換成模組B定義的global的地址。連結過程又分為符號解析和重定位:

  • a)符號解析:解決各個模組符號表中的unsolved symbol。
  • b)重定位:模組被拼接起來之後,模組符號表中的符號地址將不再正確(因為模組拼接起來後,本來的0位移,變成了有位移量)。重定位的任務就是將這些模組的匯出符號和匯入符號的引用地址最終填寫完整。

在連結階段出現最多的錯誤主要有:引用未找到、重複定義。
引用未找到:就是在符號解析階段沒有找到unsolved symbol。針對上面global的例子,這個錯誤時因為連結器無法在其他任何模組中找到global這個變數的定義。
重複定義:對於全域層級的變數,無論程式由多少個模組組成,對同一個變數可以由多個聲明但只能有一個定義。重複定義的情況通常是因為不同模組定義了相同的變數。

另外需要補充的是:在編譯模組的過程中,C++編譯器為了支援重載,會對變數名或函數名進行“重新命名”,比如會把fun這個名字變得面目全非,可能是fun@aBc_int_int#%$也可能是別的。extern "C" void fun(int a, int b); 則告訴編譯器在編譯fun這個函數名時按著C的規則去翻譯相應的函數名而不是C++的。

 

變數按照儲存周期(生命週期)可以分為:應用程式級和代碼塊級。在函數外定義的變數都是應用程式級的,因為他們是在編譯階段被作為代碼的一部分寫入到符號表中的,在模組中有固定的位移量;代碼塊級變數是在函數中定義的,運行時動態在棧上建立和銷毀的。
變數按照範圍分為:外部變數、自動變數、靜態變數。外部變數是程式每個模組在任何時候都能訪問;自動變數與代碼塊級變數一樣;靜態變數是在本模組的任何時候都能訪問的,特殊的情況是在函數裡面定義的靜態變數,這種變數的生命週期是整個應用程式級,但是只有定義它的函數可以訪問。
補充:

  • 有些人喜歡把全域變數的聲明和定義放在一起,這樣做,如果這個標頭檔被include的超過1次,在連結階段會出現重複定義的錯誤。

    extern char g_str[] = "123456";

  • 用static修飾的全域變數,連結器對其是“不可見”的。
  • 單獨const修飾變數與static一樣,具有模組層級別的範圍;但static不能與extern共用,const可以與extern公用使得變數變成全模組可見。

一些原則:

  • 標頭檔不要放定義,只放聲明,定義放在cpp檔案中
  • static變數最好放在.cpp中,防止變數被其他模組重複定義,浪費空間

     

參考資源

http://www.diybl.com/course/3_program/c++/cppsl/20071119/86983.html
http://hi.baidu.com/zengzhaonong/blog/item/30a47460eb8b0048eaf8f822.html
http://www.cppblog.com/woaidongmao/archive/2008/11/07/66254.aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.