C99 inline關鍵字

C99 inline


一直以來都用C++用得比較多,這個學期作操做系統的課設用回了C,結果一波內聯函數竟然連接不過去……查了查資料,C99引入的inline和C++的inline語義區別是很大的,我算是踩了這個坑。 C++的inline除了建議編譯器把函數內容內聯之外,主要的做用就是可以讓你把一個函數的定義在不一樣的編譯單元裏重複,而不會報連接錯誤。C99的inline則否則,它的語義是:app

Any function with internal linkage can be an inline function. For a function with external linkage, the following restrictions apply: If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.ide

大概能夠總結爲如下幾點:函數

  1. Internal linkage的函數總能夠用inline修飾,C代碼中常見的static inline用法就是從這來的。
  2. 在某個編譯單元中,若是某個inline函數的任意一個declaration都沒有用extern修飾,那麼這個編譯單元中的該函數定義稱爲內聯定義。編譯器能夠選擇使用內聯定義(即接受建議),也能夠不使用該定義,此時至關於這個定義不存在(即這個函數的調用須要連接其餘編譯單元的符號)。
  3. 內聯定義其實是提供了對外部連接函數的一個「替代方案」。好比你在a.c中已經有了函數foo的定義,可是你在b.c中又給了個foo的內聯定義,那麼編譯器可能會用b.c中給的內聯定義,也可能視之不見。

因此C語言的inline語義的正確使用方法應該有下面三種:spa

static inline,不解釋:操作系統

// a.h
static inline int func(int x) { /* ... */ }

這樣作能夠模仿C++的inline語義:rest

// a.h
inline int func(int x) { /* ... */ }

// a.c
extern int func(int x);

提供函數的「內聯版本」,由編譯器進行選擇:code

// a.h
int func(int x);

//a.c
int func(int x) { /* implementation [1] */ }

// b.c
inline int func(int x) { /* implementation [2] */ }
void A(void)
{
    //...
    i = func(j);
    //...
}

最後一種用法中,implementation [1]和implementation [2]能夠是不同的。也就是說,咱們能夠爲已有的函數提供一個「內聯版本」,這個版本不須要和原版相同。至於用哪一個,則由編譯器決定。ci

相關文章
相關標籤/搜索