Ⅰ 內聯函數的定義對編譯器而言必須是可見的什麼意思
解答其實已經說得很清楚了,編譯器在看到程序中調用普通函數的代碼時,是在這里填一個函數的地址,然後在執行時跳轉到函數那邊去。而碰到內聯函數時,是將函數的內容全部在調用點展開,所以它必須知道這個內聯函數的定義是什麼,否則無法展開。而將內聯函數的定義放在頭文件(.h)中,一旦include了該頭文件,就能看到內聯函數的全部內容了,也就可以在調用點完全展開內聯函數。如果將內聯函數放在源文件中(.c),編譯器在看到內聯函數的調用時,是無法知道內聯函數的內容的,因此也無法展開,所以必須將內聯函數定義在頭文件中。
Ⅱ 什麼是內聯函數
在計算機科學中,內聯函數(有時稱作在線函數或編譯時期展開函數)是一種編程語言結構,用來建議編譯器對一些特殊函數進行內聯擴展(有時稱作在線擴展)。
內聯擴展是一種特別的用於消除調用函數時所造成的固有的時間消耗方法。一般用於能夠快速執行的函數,因為在這種情況下函數調用的時間消耗顯得更為突出。這種方法對於很小的函數也有空間上的益處,並且它也使得一些其他的優化成為可能。
沒有了內聯函式,程式員難以控制哪些函數內聯哪些不內聯;由編譯器自行決定是否內聯。加上這種控制維度准許特定於應用的知識,諸如執行函式的頻繁程度,被利用於選擇哪些函數要內聯。
此外,在一些語言中,內聯函數與編譯模型聯系緊密:如在C++中,有必要在每個使用它的模塊中定義一個內聯函數;與之相對應的,普通函數必須定義在單個模塊中。這使得模塊編譯獨立於其他的模塊。
(2)編譯器內聯函數擴展閱讀:
在C++中我們通常定義以下函數來求兩個整數的最大值:
代碼如下:
int max(int a, int b)
{
return a > b ? a : b;
}
為這么一個小的操作定義一個函數的好處有:
① 閱讀和理解函數 max 的調用,要比讀一條等價的條件表達式並解釋它的含義要容易得多
② 如果需要做任何修改,修改函數要比找出並修改每一處等價表達式容易得多
③ 使用函數可以確保統一的行為,每個測試都保證以相同的方式實現
④ 函數可以重用,不必為其他應用程序重寫代碼
雖然有這么多好處,但是寫成函數有一個潛在的缺點:調用函數比求解等價表達式要慢得多。在大多數的機器上,調用函數都要做很多工作:調用前要先保存寄存器,並在返回時恢復,復制實參,程序還必須轉向一個新位置執行
C++中支持內聯函數,其目的是為了提高函數的執行效率,用關鍵字 inline 放在函數定義(注意是定義而非聲明,下文繼續講到)的前面即可將函數指定為內聯函數,內聯函數通常就是將它在程序中的每個調用點上「內聯地」展開。
內聯函數應該在頭文件中定義,這一點不同於其他函數。編譯器在調用點內聯展開函數的代碼時,必須能夠找到 inline 函數的定義才能將調用函數替換為函數代碼,而對於在頭文件中僅有函數聲明是不夠的。
當然內聯函數定義也可以放在源文件中,但此時只有定義的那個源文件可以用它,而且必須為每個源文件拷貝一份定義(即每個源文件里的定義必須是完全相同的),當然即使是放在頭文件中,也是對每個定義做一份拷貝,只不過是編譯器替你完成這種拷貝罷了。
但相比於放在源文件中,放在頭文件中既能夠確保調用函數是定義是相同的,又能夠保證在調用點能夠找到函數定義從而完成內聯(替換)。
Ⅲ C++內聯函數具體有什麼作用
內聯函數可減少cpu的系統開銷,並且程序的整體速度將加快,但當內聯函數很大時,會有相反的作用,因此一般比較小的函數才使用內聯函數。
內聯函數是C++的增強特性之一,用來降低程序的運行時間。當內聯函數收到編譯器的指示時,即可發生內聯:編譯器將使用函數的定義體來替代函數調用語句,這種替代行為發生在編譯階段而非程序運行階段。
值得注意的是,內聯函數僅僅是對編譯器的內聯建議,編譯器是否覺得採取你的建議取決於函數是否符合內聯的有利條件。如何函數體非常大,那麼編譯器將忽略函數的內聯聲明,而將內聯函數作為普通函數處理。
內聯函數具有一般函數的特性,它與一般函數所不同之處公在於函數調用的處理。一般函數進行調用時,要將程序執行權轉到被調用函數中,然後再返回到調用它的函數中;而內聯函數在調用時,是將調用表達式用內聯函數體來替換。在使用內聯函數時,應注意如下幾點:
1、類內定義的函數是內聯函數,類外定義的函數是非內聯函數(短函數可以定義在類內,長函數可以定義在類外)。
2、可以為類外定義的函數指定 inline 關鍵字,強行為內聯函數。
3、在內聯函數內不允許用循環語句和開關語句。
4、內聯函數的定義必須出現在內聯函數第一次被調用之前。
Ⅳ C++編譯器(Dev-C)是否會自動內聯函數 對於什麼樣的函數即使標記inline也會拒絕內聯
G++編譯器是否會自動進行內聯函數?
G++編譯器是很先進的,編譯的時候如果開啟優化,G++會代碼進行各種優化,如:對合適的函數進行內聯(即便是沒有添加inline關鍵字),對某些函數直接對其進行求值,除此之外G++編譯器還可以對代碼進行重排序 等等。編譯器比你更了解硬體,所以只要允許它優化,他會盡量進行優化。你使用的Dev C++集成開發環境使用的c++編譯器就是G++。
什麼樣的函數即使標記inline也無法內聯?
比如函數體太大、太復雜的話(比如包含多重循環、包含遞歸調用),對其進行內聯得不償失,這時編譯器就會忽略inline關鍵字,VC++編譯器提供了強制內聯函數的關鍵字,除非你非常了解硬體,不然最好讓編譯器來處。編譯不對那些函數進行內聯要看具體的編譯器實現了。
inline關鍵字的有哪些作用?
inline關鍵字可以提示編譯器對某個函數進行內聯,並且強制函數使用內部鏈接。比如說你在頭文件定義了某個函數,為了防止多重定義,你可以添加inline關鍵字來防止多重定義錯誤。
如果對硬體不是很了解,底層的代碼優化還是留給編譯器來處理。
看看下面的幾個編譯器優化函數的例子:
1.編譯器直接對函數求值:
解釋一下:
第一條和第二天指令分別將b和a的地址載入到寄存器rdx和rcx中
第三條指令將b的值載入到eax寄存器中
第四條指令將34存入b中
第五條指令將eax的值加1(eax保存了之前b的值)
第六條指令將eax的值存入a中
可以看出編譯器將函數的兩條語句換了位置,這種優化主要是優化代碼的執行速度,有的CPU內存讀寫操作的的開銷不一樣,所以重新排序一下某些代碼能夠提高程序執行速度。