热门问题
时间线
聊天
视角

行內函式

来自维基百科,自由的百科全书

Remove ads

電腦科學中,行內函式(英語:inline function,有時稱作在線函式編譯時期展開函式)是一種程式語言結構,用來建議編譯器對一些特殊函式進行行內展開(有時稱作在線擴展);也就是說建議編譯器將指定的函式體插入並取代每一處調用該函式的地方(上下文),從而節省了每次調用函式帶來的額外時間開支。但在選擇使用內聯函式時,必須在程式佔用空間和程式執行效率之間進行權衡,因為過多的比較複雜的函式進行內聯擴展將帶來很大的儲存資源開支。另外還需要特別注意的是對遞迴函式的內聯擴展可能引起部分編譯器的無窮編譯。

設計行內函式的動機

行內擴充是一種特別的用於消除呼叫函式時所造成的原生的時間消耗方法。一般用於能夠快速執行的函式,因為在這種情況下函式呼叫的時間消耗顯得更為突出。這種方法對於很小的函式也有空間上的益處,並且它也使得一些其他的最佳化成為可能。

沒有了內聯函式,程式員難以控制哪些函式內聯哪些不內聯;由編譯器自行決定是否內聯。加上這種控制維度准許特定於應用的知識,諸如執行函式的頻繁程度,被利用於選擇哪些函式要內聯。

此外,在一些語言中,行內函式與編譯模型聯絡緊密:如在C++中,有必要在每個使用它的模組中定義一個行內函式;與之相對應的,普通函式必須定義在單個模組中。這使得模組編譯獨立於其他的模組。

與巨集的比較

通常,在C語言中,行內展開的功能由帶參巨集(Macros)在原始碼級實現。行內提供了幾個更好的方法:

  • 巨集呼叫並不執行型別檢查,甚至連正常參數也不檢查,但是函式呼叫卻要檢查。
  • C語言的巨集使用的是文字替換,可能導致無法預料的後果,因為需要重新計算參數和操作順序
  • 在巨集中的編譯錯誤很難發現,因為它們參照的是擴充的程式碼,而不是程式設計師鍵入的。
  • 許多結構體使用巨集或者使用不同的語法來表達很難理解。行內函式使用與普通函式相同的語言,可以隨意的行內和不行內。
  • 行內程式碼的除錯資訊通常比擴充的巨集程式碼更有用。

語言支援

C++C99C11GNU C都支援行內函式,最被廣泛使用的C標準1989 ANSI C則不支援。在Ada中,關鍵字「pragma」可以用來聲明行內。其他的大部分程式語言,包括Java和函數式語言,不支援行內函式,但他們的編譯器常常進行強制性的行內擴充。不同的編譯器在行內擴充上有處理不同複雜程度函式的能力。主流的C++編譯器如Visual C++GCC提供了一個選項來自動行內任何一個合適的函式,即使它們沒有被聲明為行內函式。

對於C++,inlineextern inline同義:行內函式在各個編譯單元都可能會生成一份,要求各處定義完全一致。行內函式在C++中的寫法如下:

inline int max (int a, int b) {
    if (a > b) 
    return a; 
    else 
    return b; 
}
a = max (x, y); // 等价于 "a = (x > y ? x : y);"

對於C99,inline為編譯單元內部可見,extern inline為編譯單元外部也可見。

行內函式的不足

除了通常使用行內擴充可能帶來的問題,作為一種程式語言特性的行內函式也可能並沒有看起來那麼有效,原因如下:

  • 通常,編譯器比程式設計者更清楚對於一個特定的函式是否合適進行行內擴充;一些情況下,對於程式設計師指定的某些行內函式,編譯器可能更傾向於不使用行內甚至根本無法完成行內。
  • 對於一些開發中的函式,它們可能從原來的不適合行內擴充變得適合或者倒過來。儘管行內函式或者非行內函式的轉換易於巨集的轉換,但增加的維護開支還是使得它的優點顯得更不突出了。
  • 對於基於C的編譯系統,行內函式的使用可能大大增加編譯時間,因為每個呼叫該函式的地方都需要替換成函式體,程式碼量的增加也同時帶來了潛在的編譯時間的增加。

參見

外部連結

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads