inline函數有兩種聲明形式,一種是static __inline__,另一種是extern __inline__,inline不都是要展開的么,那么這兩種形式有什么不同呢?還是只是形式上的不同?
如果一個函數既是inline又是static,如果所有對函數的調用都能被展開在調用者里面,並且這個函數的地址從來沒有被使用過,那么這種 情況下不存在對這個函數本身匯編代碼的引用。這時,GNU CC實際上並不輸出這個函數的匯編代碼,除非加選項“-fkeep-inline-functions”。存在一些由於各種原因不能被展開的調用(比如, 在函數聲明前的調用不能被展開,定義中的遞歸調用同樣也不行)。如果存在未展開的函數調用,那么這個函數象通常一樣被編譯生成匯編代碼。如果這個函數被通 過地址引用,那么這個函數也必須象一般函數那樣被編譯生成,因為那樣的引用不能夠被展開(inlined)。
當一個inline函數不是 static時,那么編譯器必須假設其他源程序中可能存在調用,因為一個全局符號只能被定義一次,所以這個函數在其他源程序中不能被定義,於是那里的調用 不能夠被展開。因此,一個非static的inline函數總是同普通函數一樣被編譯生成。
如果函數聲明中同時使用了inline和extern,那么這個定義只被用來inline展開。這個函數體的匯編代碼從來都不會被編譯生成,即使你顯示引用了它的地址,顯示引用的地址變成一個外部引用,就像你僅僅聲明了這個函數,而沒有定義它一樣。
inline 和extern的結合幾乎達到一個宏定義的效果。使用它的方法是在頭文件中使用這些關鍵字寫出函數定義,同時在庫文件中放入另一份函數體定義的拷貝(沒有 inline和extern)。在頭文件中的定義將會使大部分對函數的調用被inline展開。如果存在對這個函數的使用,它們將會引用庫中的單一拷貝。
當一個inline函數不是 static時,那么編譯器必須假設其他源程序中可能存在調用,因為一個全局符號只能被定義一次,所以這個函數在其他源程序中不能被定義,於是那里的調用 不能夠被展開。因此,一個非static的inline函數總是同普通函數一樣被編譯生成。
如果函數聲明中同時使用了inline和extern,那么這個定義只被用來inline展開。這個函數體的匯編代碼從來都不會被編譯生成,即使你顯示引用了它的地址,顯示引用的地址變成一個外部引用,就像你僅僅聲明了這個函數,而沒有定義它一樣。
inline 和extern的結合幾乎達到一個宏定義的效果。使用它的方法是在頭文件中使用這些關鍵字寫出函數定義,同時在庫文件中放入另一份函數體定義的拷貝(沒有 inline和extern)。在頭文件中的定義將會使大部分對函數的調用被inline展開。如果存在對這個函數的使用,它們將會引用庫中的單一拷貝。