[英]gcc - 2 versions, different treatment of inline functions
最近我在我的項目中遇到了一個問題。 我通常在gcc-4中編譯它,但在嘗試在gcc-3中編譯之后,我注意到了對內聯函數的不同處理。 為了說明這一點,我創建了一個簡單的例子:
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.c
和file.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被打破了,除非它們是靜態的,否則我不應該在一些翻譯單元中有多個內聯函數的定義?
是的,行為已經從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版本的可移植性使用靜態內聯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.