久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

關(guān)于 extern inline | A Geek''''s Page

 astrotycoon 2018-05-15

(本文是《C語言編程藝術(shù)》的一部分,轉(zhuǎn)載請注明出處,,勿用于商業(yè)用途,。)

大家一定對C語言 inline 關(guān)鍵字不陌生,甚至經(jīng)常用到 static inline 的函數(shù),??赡芨械侥吧氖?extern inline。C11 標(biāo)準(zhǔn)在6.7.4 p7 中對此進(jìn)行了描述,,不過比較生澀難讀,。簡單地講,static line 和 extern inline 的區(qū)別,,從名字上也能看得出來,,就是編譯單元之外可見性的問題。把一個普通函數(shù)給內(nèi)聯(lián)掉之后,,一個顯著的區(qū)別就是外部可見性沒了,,怎么能同時(shí)既能內(nèi)聯(lián)又能保留外部的可見性呢?為了解決這個問題就有了extern inline,。

static inline 是說這個函數(shù)就這么一個,,而且沒有外部可見性,在所有的編譯單元中大家必須共用這么一個定義,,這也是為什么 static inline 通常要放到頭文件中的原因,;而 extern inline 就不一樣了,它是說這個函數(shù)雖然只有一個定義,,但是既有內(nèi)聯(lián)的版本,,也有非內(nèi)聯(lián)的版本,,如果你能看得到它的定義,。即在同一個編譯單元中,那么你就可以用它的內(nèi)聯(lián)版本,;看不到的話,,你就可以用非內(nèi)聯(lián)版本,即和其它普通函數(shù)一模一樣。

而如果既不帶 static 也不帶 extern 的話,,含義又不同了:前面的 extern inline 只需要定義一次,,只是不同的地方看到的版本不同,有的地方看到的是內(nèi)聯(lián)的版本,,而有的地方看到的只是個 external reference,。而僅用 inline 的話,就變成了要定義兩次,,帶 inline 關(guān)鍵字的這個定義就是內(nèi)聯(lián)版本,,在這個編譯單元中都用這個版本,而在外部,,還是使用普通的非內(nèi)聯(lián)定義,。換句話說,帶 inline 的定義遮蓋住了外部的定義,。既然有兩個不同的版本,,那么也就需要保持這兩個版本的定義相同,否則就會有問題,。

以上是標(biāo)準(zhǔn)C的定義,,而 GNU89 的定義就不同了,基本上是把”extern inline”和”inline”的含義給交換了,,“static line” 的含義都是相同的,。看下面的標(biāo)準(zhǔn)C的例子:

[c]
//a.c
//C99
extern inline int max(int a, int b)
{
return a > b ? a : b;
}

int a = 10;
int b = 20;
int foo(void)
{
return max(a, b);
}

extern int bar(void);

int main(void)
{
return foo() + bar();
}

//b.c
//C99
extern int max(int a, int b);

int bar(void)
{
int a = 10;
int b = 20;
return max(a, b);
}
[/c]

我們這么編譯:
% gcc -std=c99 -O2 -Wall -W a.c b.c -o c

而我們?nèi)绻阉幾g成 GNU89 的話,,就會報(bào)錯:
% gcc -std=gnu89 -O2 -Wall -W a.c b.c -o c
/tmp/ccAJTzwY.o: In function bar': b.c:(.text+0xb): undefined reference tomax’
collect2: ld returned 1 exit status

很明顯,,因?yàn)?GNU89 中的 extern inline 需要兩個定義,明顯我們少了一個,。修改后的代碼如下:

[c]
//a.c
//GNU89
extern inline int max(int a, int b)
{
return a > b ? a : b;
}

int a = 10;
int b = 20;
int foo(void)
{
return max(a, b);
}

extern int bar(void);

int main(void)
{
return foo() + bar();
}

// b.c
//GNU89
int max(int a, int b)
{
return a > b ? a : b;
}

int bar(void)
{
int a = 10;
int b = 20;
return max(a, b);
}
[/c]

glibc 中就用到了 GNU89 的extern inline 特性,,在 ctype.h 中,tolower()/toupper() 的定義是:
[c]

ifdef __USE_EXTERN_INLINES

extern_inline int NTH (tolower (int c))
{
return
c >= -128 && c = -128 && c = -128 && c = -128 && c < 256 ? __ctype_toupper[c] : c;
}
[/c]

順便說一句,,gcc 提供了-fgnu89-inline 和 -fno-gnu89-inline 選項(xiàng)可在編譯時(shí)控制上述 inline 的行為,。

Stackoverflow 上有人做了一個很好的總結(jié),我翻譯了一下:

GNU89:

"inline": 函數(shù)可能會被內(nèi)聯(lián)掉,,非內(nèi)聯(lián)的版本總是會生成,,而且外部可見,因此內(nèi)聯(lián)的定義在本編譯單元中只能有一次,,其它地方看到的是非內(nèi)聯(lián)版本,。

"static inline":不會生成外部可見的非內(nèi)聯(lián)版本,可能會生成一個 static 的非內(nèi)聯(lián)版本,。它當(dāng)然可以被定義多次,,因?yàn)橥獠靠床坏剿?
"extern inline":不會生成一個非內(nèi)聯(lián)的版本,,但是可以調(diào)用一個非內(nèi)聯(lián)版本(因此你必須在其它編譯單元中定義它)。只能有一個定義的規(guī)則當(dāng)然也適用,,非內(nèi)聯(lián)版本和內(nèi)聯(lián)版本的代碼必須是一樣的,。

C99 (or GNU99):

"inline":和 GNU89 的 "extern inline" 一樣,沒有外部可見的函數(shù)生成,,但是外部可見的函數(shù)必須存在,,因?yàn)橛锌赡軙玫剿?
"extern inline":和 GNU89 的 "inline" 一樣, 會生成外部可見的代碼,,最多一個編譯單元可以使用它,。

"static inline":和 GNU89 的 "static inline" 一樣,這是唯一一個在 GNU89 和 C99之間可移植的,。

最后,,我們可以看大神 Linus Torvalds 如何描述 extern inline:

“static inline” means “we have to have this function, if you use it, but don’t inline it, then make a static version of it in this compilation unit”. “extern inline” means “I actually have an extern for this function, but if you want to inline it, here’s the inline-version”.

參考資料:
http://www./rjk/tech/inline.html
http://gcc./ml/gcc/2006-11/msg00006.html
http:///questions/6312597/is-inline-without-static-or-extern-ever-useful-in-c99
http://www.cnblogs.com/cnmaizi/archive/2011/01/19/1939686.html

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多