簡體   English   中英

gcc - 2個版本,內聯函數的不同處理

[英]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.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被打破了,除非它們是靜態的,否則我不應該在一些翻譯單元中有多個內聯函數的定義?

是的,行為已經從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.

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