[英]C99 inline function in .c file
我在 .c 中定義了我的函數(沒有頭聲明),如下所示:
inline int func(int i) {
return i+1;
}
然后在下面的同一個文件中我使用它:
...
i = func(i);
在鏈接期間,我得到了“對‘func’的未定義引用”。 為什么?
C99 中的inline
模型與大多數人認為的有點不同,特別是與 C++ 使用的不同
inline
只是一個提示,以便編譯器不會抱怨雙重定義的符號。 如果需要,它不保證函數是內聯的,也不保證實際上生成符號。 要強制生成符號,您必須在內inline
定義之后添加一種實例化:
int func(int i);
通常,您會在頭文件中包含inline
定義,然后將其包含在多個 .c 文件(編譯單元)中。 並且您只會在編譯單元之一中包含上述行。 您可能只會看到您遇到的問題,因為您沒有對編譯器運行進行優化。
因此,您在 .c 文件中使用inline
用例沒有多大意義,最好為此使用static
,即使額外的inline
也不會給您帶來太多好處。
C99 內聯語義經常被誤解。 inline
說明符有兩個用途:
首先,作為static inline
和extern inline
聲明的編譯器提示。 如果刪除說明符,語義將保持不變。
其次,在原始inline
(即沒有static
或extern
)的情況下,提供內聯定義作為外部定義的替代,外部定義必須存在於不同的翻譯單元中。 不提供外部是未定義的行為,通常表現為鏈接失敗。
如果您想將一個函數放入一個共享庫,同時又使函數體可用於優化(例如內聯或特化),這將特別有用。 假設編譯器足夠智能,這允許您恢復 C++ 模板的許多好處,而無需跳過預處理器。
請注意,它比我在此處描述的更混亂,因為具有另一個文件范圍的非內聯外部聲明將觸發 Jens 的回答中描述的第一種情況,即使定義本身是inline
而不是extern inline
。 這是設計使然,因此您可以在頭文件中有一個內聯定義,您可以通過為外部聲明添加一行來將其包含到提供外部定義的源文件中。
這是因為 GCC 處理內聯函數的方式。 GCC 執行內聯替換作為優化的一部分。
要消除此錯誤,請在內聯之前使用static
。 使用static
關鍵字強制編譯器內聯此函數,從而使程序編譯成功。
static inline int func(int i) {
return i+1;
}
...
i = func(i);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.