簡體   English   中英

C99中的inline,static,extern

[英]inline, static, extern in C99

請不要在這里重定向到那里的答案 - 我已經閱讀了它們,以及互聯網上的其他答案,包括標准,但我仍然感到困惑(大多數情況下,我認為是因為技術詞匯,英語單詞和語言的重疊關鍵字)。


讓我在C99中直截了當地了解函數

static :不產生任何外部符號

extern (隱式):如果此轉換單元中沒有定義,則編譯器會生成在鏈接期間解析的引用


現在有了inline 據我所知,由於編譯器可能選擇內聯或不內聯,因此問題很復雜。

  • 如果編譯器決定內聯,顯然實現必須在編譯時可見
  • 如果編譯器決定不內聯,哪個函數被鏈接,以及該代碼在哪個翻譯單元中存在?

我可以通過兩種不同的方式看到這個答案:

  1. 如果編譯器決定不在某個調用站點內聯函數,則在同一個轉換單元內生成非內聯對象代碼。 不會為此導出外部符號。
  2. 如果編譯器決定不在某個調用站點內聯函數,那么這表現為普通函數,並且必須有一個轉換單元導出外部符號並包含實現該函數的目標代碼。

static inline似乎是#1的答案:

  • 如果編譯器決定內聯static inline函數,那么就去做吧。 static存儲說明符與非內聯函數的使用一致,因為不會產生外部符號。 由於這種情況,如果編譯器決定在轉換單元內的每個調用站點內聯static inline函數,則不需要生成獨立的目標代碼。
  • 如果編譯器決定不在某個調用站點內聯static inline函數,那么它可以在轉換單元內生成獨立的目標代碼,並且不會為其導出外部符號。

據我所知, extern inline / inline是#2的答案:

  • 所有inline (沒有externstatic )的行為類似於#2。 如果編譯器實際上沒有內聯它們,那么在鏈接時需要鏈接外部實現。
  • 實際導出要鏈接的符號的翻譯單元必須聲明為extern inline 我認為這是最令人困惑的,因為正常函數的extern關鍵字幾乎完全相反

它是否正確?


相關鏈接,但仍然留下模糊的角落:

沒有“靜態”或“外部”的“內聯”在C99中是否有用?

外部內聯

新C:內聯函數

您對此的總體理解是正確的。

實際導出要鏈接的符號的翻譯單元必須聲明為extern inline。 我認為這是最令人困惑的,因為正常函數的extern關鍵字幾乎完全相反

是的,這是該語言的一個不幸的部分,但你有權利。


作為一小部分瑣事(希望不會讓你感到困惑),GNU gcc 用於處理“內聯”和“外部內聯”與C99 / C11標准對待它們的方式完全相反。 在這種情況下,GNU會將“內聯”解釋為“使用此定義以內聯AND生成此函數的外部,外部可見定義”,並將“extern inline”視為“僅使用此定義進行內聯” ;如果沒有發生內聯,則發出對函數的extern引用(必須在別處定義)“。

無論出於何種原因,C99標准選擇交換“內聯”和“外部內聯”的含義,現在我們堅持使用它。

注意:快速測試表明,如果不通過-std = c99 / c11或-fno-gnu89-inline,GNU gcc v4.9.2將默認采用“GNU”方式(-fgnu89-inline)。 在那時和GNU gcc v5.2.1之間的某個時間它發生了變化,因為v5.2.1將默認為-fno-gnu89-inline(即標准的C99 / C11方式)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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