回答
它不應該是順序依賴的。唯一相關的步驟如下:
- 每個編譯單元包括它依賴的內容,應該單獨編譯。這意味着,首先,每個CPP文件包含它所依賴的所有標題;其次,每個頭文件應該包含它所需要的內容,以便它可以編譯,即使它是第一個被編譯的。
- 鏈接步驟將所有編譯的目標代碼放在一起並生成最終的二進制文件。
這取決於環境。一般來說,「編譯器」一次只能在單個源文件上工作;您使用更高級的工具來引導它並計算正確的構建順序。
此類工具的示例可以是make,ant,CMake,SCons,Eclipse和Visual Studio。基本檢查通常是源代碼文件的修改日期,以及定義各種輸出文件如何依賴於輸入的內置和自定義規則。
無關。發佈確切的問題。編譯順序是非確定性和任意的,並且不會影響項目的可編譯性。
事實上,甚至可能沒有編譯分配的編譯命令。如果它發生在不同的機器上,你不能說在b.cpp之前或之後編譯a.cpp。 – MSalters 2009-12-15 11:18:57
它不應該的問題它開始哪個文件,所有文件都被編譯
編譯器編譯中不應該有所作爲,正如其他人指出的順序後,鏈接器解析外部引用。
從編譯器的角度來看,當您編譯一個帶有#include
的文件時,包含的文件會插入正在編譯的文件中#include
所在的位置,並在必要時進行遞歸。
正如其他人所指出的那樣,從概念上講,從哪個文件開始並不重要。但是,從具有最多依賴性的文件開始使用最近編輯的文件(假定編輯了多個文件)可能很有用。某些環境(如Code :: Blocks)實際上允許您對源文件進行加權,以使您能夠控制編譯順序。
我能想到的唯一的「包含依賴」問題是遞歸包含。對於其修復通常與#ifdef
#ifndef INCLUDED_THEFILENAME_H
#define INCLUDED_THEFILENAME_H
/* content goes here *
#endif
守着,但你最好在你所遇到的問題的闡述。
請注意,名稱__THEFILENAME_H在用戶編寫的C++代碼中是非法的。 – 2009-12-14 13:14:12
uhm ...對於宏?好吧,無論如何,這個名字是無關緊要的。 – 2009-12-14 13:21:58
@ hacker:即使是宏,你仍然不應該有前導下劃線。對於一個宏來說,大寫就足夠了,當你有'_H''結尾時,它就是一個包含守衛的充分慣例。 – quamrana 2009-12-14 13:27:06
其他人已經表示,訂單不應該有所作爲。
你可能沒有意識到的是編譯器編譯每.cpp
或.cc
文件。它確實不是編譯頭文件。而且通常情況下,您只有#include
頭文件,而永不.cpp
文件,所以順序無關緊要。每個.cpp
文件都是獨立處理的。它包含許多標題,但這些標題永遠不會單獨編譯,而且它的確不是而是通常還包含其他.cpp
文件。
它不編譯頭文件?如果一個類在頭文件中包含所有的代碼,並且沒有cpp文件呢? – clamp 2009-12-14 15:11:37
Jalf的含義(甚至在後面的段落中提到)是編譯器通常不會自己編譯頭文件*。相反,它通過編譯包含它的.cpp文件隱式編譯頭文件,從這個意義上講,頭文件經常被編譯*多次*,每個包含它的源文件編譯一次。鏈接器將所有重複都作爲最終構建步驟進行分類。 – 2009-12-14 16:53:58
是的。編譯器處理「翻譯單元」。一個翻譯單元是一個.cpp文件的結果,並且複製/粘貼所有'#inc'並評估所有的宏。所以編譯器看到的基本上是一個.cpp文件,並附有所有頭文件。但它從不編譯頭文件* *。 – jalf 2009-12-14 17:42:14
make工具構建make文件中指定的依賴項的有向非循環圖。這通常會說可執行文件取決於一些目標文件。目標文件依賴於源文件,每個源文件都依賴於頭文件等等。
這基本上生成一個多路樹。該樹將以可執行文件爲根,並且通常主要包含葉節點的標題(儘管如果您使用的是某種代碼生成器,它也可以將該代碼生成器的輸入文件作爲葉)。
然後,它走過那棵從葉節點到根節點的樹,然後繼續建築。說「無關緊要」的答案基本上指出,它可以選擇樹的任何一個分支來構建第一個分支。但是,當它選擇一個分支時,它會按照爲該分支指定的順序進行構建。
- 1. .NET命令行編譯器在哪裏?
- 2. Android庫在哪裏編譯?
- 3. 快速問題:位於Windows中的C++編譯器在哪裏?
- 4. 我可以在哪裏閱讀C#編譯器的功能?
- 5. 從哪裏下載Turbo或Borland C/C++編譯器+ IDE?
- 6. 哪裏可以找到Eclipse編譯器?
- 7. Linux C++編譯器(和鏈接器)如何決定將typeinfo放在哪裏?
- 8. zip.so在哪裏編譯安裝php 5.3.9
- 9. 在哪裏編碼啓發式?
- 10. 從哪裏啓動AlarmManager?
- 11. .NET中編譯C#程序後的MSIL文件在哪裏?
- 12. 無需Visual Studio 2010,我可以在哪裏下載C#4.0的編譯器?
- 13. 在哪裏以及如何在根啓動器主題中添加/編輯css
- 14. java編譯器的源代碼在哪裏?
- 15. Visual Studio的編譯器在哪裏搜索#includes?
- 16. 指定Maven編譯器使用的JDK版本在哪裏?
- 17. Flex編譯器將.aso文件放在哪裏?
- 18. 在哪裏可以找到VisualC++ x64命令行編譯器?
- 19. CSC編譯器在哪裏生成PE文件?
- 20. 告訴TypeScript編譯器在哪裏查找非相關模塊
- 21. 如何在C++中編譯編譯器?
- 22. Tomcat無法啓動。我錯在哪裏?
- 23. 終端:shell啓動文件在哪裏?
- 24. Python啓動橫幅在哪裏定義?
- 25. 啓動現代編譯器時出錯
- 26. 用C++編譯器編譯c代碼
- 27. 不能在eclipse裏編譯C++
- 28. 爲什麼C#編譯器第二次啓動?
- 29. Avada(WordPress主題)編譯CSS:它從哪裏編譯?
- 30. 啓動服務啓動後的位置在哪裏?
@Daniel:您還可以添加每個頭還應該包含它所依賴的內容,以便即使它是模塊包含的第一個頭也會進行編譯。 – quamrana 2009-12-14 13:29:31
謝謝@quamrana,我試圖將你的評論納入我的答案。 – 2009-12-14 13:44:19
我的方式是:只包含一個'#include'的源文件應該始終編譯(到.o文件)而不會出錯。我使用了一個「hcheck」腳本,它創建了一個.c或.cc文件,它包含在命令行中指定的文件,然後嘗試編譯它,並刪除臨時.c/.cc文件完成。 – 2009-12-14 14:15:02