2015-06-26 82 views
-2

我正在研究一個包含多個模塊(源文件,頭文件,庫)的項目。所有這些湯中的一個文件包含我的主要功能。編譯器如何知道我的主函數在哪裏?

我的問題是:

  • 編譯器如何知道哪個模塊編譯和不呢?
  • 編譯器如何識別帶有main()的模塊?
+0

閱讀關於編譯器的階段,你會得到答案。 – haccks

+0

它沒有。 [enuf character for this comment] –

+0

編譯器不關心main函數,並會編譯所有的編譯單元。稍後的鏈接器將鏈接這些鏈接並可能刪除未鏈接的功能。 –

回答

0

如何編譯器知道哪些模塊編譯並沒有

它沒有。你告訴哪一個想編譯,通常是通過編譯語句存在於makefile中。

編譯器如何識別main()裏面的模塊?

總之這是一個很大的過程,this related question已經回答了。總之,在編譯帶有標準C庫的程序時,程序的入口點設置爲_start。現在在內部提供了main()函數。因此,在編譯時,沒有(需要)檢查main()的存在。在鏈接時,鏈接器應該能夠找到它可以鏈接到的一個實例main()。這樣,main()將作爲您程序的入口點。

因此,要回答

編譯器如何知道在哪裏我的主要功能是什麼?

它確實(並且不需要)。這是鏈接器的工作,具體而言。

1

編譯器本身並不關心哪個文件包含哪些函數; main()並不特別。但是,在鏈接階段,來自不同文件(和編譯單元,可能)的所有這些符號都是匹配的。鏈接器有一個隱藏的「模板」,它具有固定地址上的代碼,操作系統在運行程序時將始終調用該地址。該代碼將調用您的main;因此,鏈接程序會在所有文件中查找main。如果它不在那裏,你會得到一個未解決的符號錯誤,就像你使用了一個你忘記實現的函數一樣。

與任何其他功能相同適用於main:您只能有一個執行;在鏈接在一起的兩個文件中有兩個main,則會出現鏈接器錯誤,因爲鏈接程序無法確定要使用哪個文件。

+0

更具體地說:當編譯器在鏈接模式下調用時,它充當引用C庫的特殊運行時代碼的驅動程序。可執行頭文件中的固定地址通常是名爲'_start'的符號地址。 – o11c

0

啓動該程序的彙編代碼(通常稱爲啓動代碼,由嵌入式人員調用)具體調用main()
編譯器文檔中包含main()的原型。 當你編譯一個程序時,會產生一個目標文件。然後,源代碼中的目標文件與啓動運行時組件(通常稱爲crt0.o [bj])和C庫組件等鏈接。 如果main()更改爲無法識別的簽名,則編譯單元將抱怨未解決的外部參考_main__main