2012-07-20 57 views
2

我無法解釋我在鏈接我的代碼時看到的行爲。也許有人有一個想法是怎麼回事...包含語句在鏈接步驟中的順序如何?

我有使用GNU Automake工具作爲其構建系統(所有Linux下)的多個文件C++項目。

添加源文件和頭文件後(讓我們稱之爲util.ccutil.h)到項目,並具有調用來自新添加的文件,我具體情況取決於include得到一個鏈接錯誤的功能已經存在的源文件(calc.cc)聲明出現。我再說一遍:錯誤發生在鏈接步驟中,編譯運行良好!

例子:

calc.cc:

#include "file1.h" 
#include "file2.h" 
#include "file3.h" 
#include "file4.h" 
#include "util.h" // new header 

該版本編譯罰款:

我時,把新的包含語句在預先存在的語句的結束,就像得到一個錯誤。但鏈接產生一個錯誤(未找到符號)!

現在,當改變這

#include "util.h" // new header 
#include "file1.h" 
#include "file2.h" 
#include "file3.h" 
#include "file4.h" 

然後編譯和連接運行正常!

由於鏈接只讀取.o文件,這一定意味着不同的內容取決於其中包括出現語句生成。怎麼會這樣?

編譯爲g ++(GCC)4.4.6

+0

有可能是在'util.h'中定義的宏防止被包括在隨後的頭文件中的一個的函數或變量聲明。 – hmjd 2012-07-20 10:29:40

回答

1

機會是util.h具有改變其他文件中的一個的行爲的#define。

確定發生了什麼的最佳機會將涉及檢查這些頭文件以找到缺失符號的名稱,並通過編譯calc.cc的「工作」和「非工作」方式獲得預處理器輸出,並比較這兩個文件。

1

簡單,頭文件可以(重新)定義哪些可以改變後的宏的解釋宏。

例如,在上述的例子中,如果確實file1.h

#define lseek lseek64 

和util.h具有調用lseek的內聯函數,然後根據不同的包括順序生成的目標代碼將有一個符號上參考lseek或lseek64。

這就是爲什麼項目往往有config.h中(由autoconf生成)規則首次列入。

0

你absolutley正確的:不同的對象代碼是在兩種情況下產生的。正如@hmjd所指出的,很可能util.h中有一個宏是其中一個(.h或.c)文件使用的,並且任何未聲明的被稱爲identifier的文件都被編譯器假定爲一個函數 - 這是很可能是這裏的錯誤。