簡體   English   中英

linker 是否將 object 文件與其自身鏈接?

[英]Does linker link an object file with itself?

根據我在其他 SO 答案中讀到的內容,例如thisthis ,編譯器將源代碼轉換為 object 文件。 object 文件可能包含對printf等需要由 linker 解決的函數的引用。

我不明白的是,當聲明和定義都存在於同一個文件中時,如以下情況,編譯器或 linker 是否解析對return1的引用

或者這只是編譯器優化的一部分?

int return1();

int return2() {
  int b = return1();
  return b + 1;
}

int return1() {
  return 1;
}

int main() {
  int b = return2();
}

我通過運行g++ -E main.cpp確保預處理與此無關


2020-7-22 更新

答案都很有幫助! 謝謝!

從下面的答案來看,在我看來,編譯器可能會也可能不會解析對return1的引用。 但是,我仍然不清楚是否只有一個翻譯單元,就像我給出的示例一樣,如果編譯器沒有解決它,這是否意味着 linker必須解決它?

Since it seems to me that linker will link several (greater than one) object files together, and if there's only one translation unit (object file) , linker need to link the object file with itself, am I right?

無論如何,是否可以確定我的計算機上的情況是哪一個?

這取決於。 這兩個選項都是可能的,您沒有提到的選項也是可能的,例如編譯器或 linker 重新排列代碼以便不再存在任何函數。 最好考慮編譯器發出對函數的引用,而鏈接器將這些引用解析為理解 C++ 的一種方式,但請記住,所有編譯器和 linker 所要做的就是生成一個工作程序,並且有許多不同的方法可以做到這一點。

然而,編譯器和 linker 必須做的一件事是確保對標准庫函數的任何調用都發生(如您提到的printf ),並按照 ZF6F87C9FDCF8B3C3F07F93F1EE8712CZ 源指定的順序發生。 除此之外(以及其他一些類似的問題),他們或多或少可以隨心所欲。

[lex.phases]/1.9 ,涵蓋翻譯的最后階段,指出[強調我的]:

所有外部實體引用均已解析。 鏈接庫組件以滿足對當前翻譯中未定義的實體的外部引用。 所有此類翻譯器 output 都被收集到一個程序映像中,該程序映像包含在其執行環境中執行所需的信息。

但是,由編譯器決定庫組件是單個翻譯單元還是它們的組合; 根據[lex.separate]/2 [強調我的]:

[注意:以前翻譯的翻譯單元和實例化單元可以單獨保存或保存在庫中 程序的單獨翻譯單元通過(例如)調用標識符具有外部鏈接的函數、標識符具有外部鏈接的對象的操作或數據文件的操作來通信([basic.link])。 翻譯單元可以單獨翻譯,然后鏈接以生成可執行程序。 ——尾注]


OP:[...] 編譯器或 linker 是否解析對return1的引用?

因此,即使return1具有外部鏈接,正如它在引用它的翻譯單元中定義的那樣(在return2中),linker 也不應該需要解析對它的引用,因為它的定義存在於當前翻譯中。 然而,標准段落(可能是故意)對於何時需要進行鏈接以滿足外部引用的要求有點模糊,我認為推遲解析return1 return2引用直到鏈接階段。

實際上,問題在於以下代碼:

static int return1();

int return2() {
  int b = return1();
  return b + 1;
}

int return1() {
  return 1;
}

linker 的問題是每個翻譯單元現在都可以包含自己的return1 ,因此 linker 在選擇正確的return1時會有問題。 有一些技巧可以解決這個問題,例如將翻譯單元名稱添加到 function 名稱中。 大多數 ABI 不這樣做,但 C++ 標准允許這樣做。 然而,對於匿名命名空間,即namespace { int function1(); } namespace { int function1(); } ,ABI 將使用這樣的技巧。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM