2010-06-23 60 views
3

最近我在我的項目中遇到了一個問題。我通常在gcc-4中編譯它,但是在嘗試在gcc-3中編譯後,我注意到內聯函數的不同處理。爲了說明這一點,我已經創建了一個簡單的例子:gcc - 2個版本,內聯函數的不同處理

的main.c:

#include "header.h" 
#include <stdio.h> 

int main() 
{ 
    printf("f() %i\n", f()); 
    return 0; 
} 

file.c:

#include "header.h" 
int some_function() 
{ 
    return f(); 
} 

header.h

inline int f() 
{ 
    return 2; 
} 

當我編譯gcc-3.4.6中的代碼與:

gcc main.c file.c -std=c99 -O2 

我得到鏈接錯誤(F的多個定義),相同的,如果我刪除-O2標誌。我知道編譯器不需要內聯任何東西,如果它不想要的話,所以我假定它將f放在目標文件中,而不是在main.cfile.c的情況下內聯它,從而產生多重定義錯誤。顯然,我可以通過使f爲靜態來解決這個問題,然後在最壞的情況下,在二進制文件中有幾個f

但我試圖編譯此代碼在GCC-4.3.5有:

gcc main.c file.c -std=c99 -O2 

,一切都在二進制工作得很好,所以我認爲新的gcc內聯在這兩種情況下f,也沒有功能f在所有(在gdb中檢查,我是正確的)。

但是,當我刪除-O2標誌時,我得到了兩個未定義的對int f()的引用。 在這裏,我真的不明白髮生了什麼事。這似乎是GCC假設f會被內聯,所以也沒把它添加到目標文件,但後來(因爲沒有-O2)決定產生這些功能,而不是內聯調用而這也正是來自的鏈接錯誤。

現在問題來了:我應該如何定義,並宣佈簡單的小功能,我想在線,讓他們可以在整個項目中使用,而不在各種編譯器問題的恐懼?並且讓所有這些都是正確的做法?或者,也許gcc-4被破壞了,除非它們是靜態的,否則我不應該在幾個翻譯單元中有多個內聯函數的定義?

回答

5

是,該行爲已經從GCC-4.3起變化。 gcc內聯文檔(http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Inline.html)詳細介紹了這一點。

簡短故事:純內聯僅用於告知gcc(在舊版本中) 內聯調用來自同一文件範圍。然而,它並沒有告訴GCC是 所有來電者是從文件的範圍,從而GCC也保持一個可鏈接的版本f() 各地:這也解釋了上述的重複的符號錯誤。

的gcc 4.3改變了這種行爲與C99兼容。

而且,爲了回答您的具體問題:

現在問題來了:我應該如何定義,並宣佈簡單的小功能,我想在線,讓他們可以在整個項目中使用,而不害怕在各種編譯器中出現問題?並且讓所有這些都是正確的做法?或者,也許gcc-4被破壞了,除非它們是靜態的,否則我不應該在幾個翻譯單元中有多個內聯函數的定義?

如果您希望跨gcc版本的可移植性使用靜態內聯。

+0

謝謝,這解釋了很多 – 2010-06-23 10:00:57