內聯函式的實現機制

2021-05-23 11:39:41 字數 1332 閱讀 4832

以下摘自c++ thinking     

為了理解內聯何時有效,應該先理解編譯器遇到乙個內聯函式時將做什麼。對於任何函式,

編譯器在它的符號表裡放入函式型別(即包括名字和引數型別的函式原型及函式的返回型別)。

另外,編譯器看到內聯函式和內聯函式的分析沒有錯誤時,函式的**也被放入符號表。**

是以源程式形式存放還是以編譯過的彙編指令形式存放取決於編譯器。

呼叫乙個內聯函式時,編譯器首先確保呼叫正確,即所有的引數型別必須是正確型別或編

譯器必須能夠將型別轉換為正確型別,並且返回值在目標表示式裡應該是正確型別或可改變為

正確型別。當然,編譯器對任何型別函式都是這樣做的,這與預處理器顯著不同,因為預處理

器不能檢查型別和進行轉換。

假如所有的函式型別資訊符合呼叫的上下文的話,內聯函式**就會直接替換函式呼叫,

消除了呼叫的開銷。假如內聯函式也是成員函式,物件的位址( t h i s )就會被放入合適的地方,

這當然也是預處理器不能執行的。

以下摘自 http://topic.csdn.net/t/20030630/22/1975426.html

讓我們看看c++   的「函式內聯」是如何工作的。對於任何內聯函式,編譯器在符號表裡放入函式的宣告(包括名字、引數型別、返回值型別)。如果編譯器沒有發現內聯函式存在錯誤,那麼該函式的**也被放入符號表裡。在呼叫乙個內聯函式時,編譯器首先檢查呼叫是否正確(進行型別安全檢查,或者進行自動型別轉換,當然對所有的函式都一樣)。如果正確,內聯函式的**就會直接替換函式呼叫,於是省去了函式呼叫的開銷。這個過程與預處理有顯著的不同,因為預處理器不能進行型別安全檢查,或者進行自動型別轉換。假如內聯函式是成員函式,物件的位址(this)會被放在合適的地方,這也是預處理器辦不到的。

c++   語言的函式內聯機制既具備巨集**的效率,又增加了安全性,而且可以自由操作類的資料成員。所以在c++   程式中,應該用內聯函式取代所有巨集**,「斷言assert」恐怕是唯一的例外 。assert是僅在debug版本起作用的巨集,它用於檢查「不應該」發生的情況。為了不在程式的debug版本和release版本引起差別,assert不應該產生任何***。如果assert是函式,由於函式呼叫會引起記憶體、**的變動,那麼將導致debug版本與release版本存在差異。所以assert不是函式,而是巨集。

inline是一種「用於實現的關鍵字」,而不是一種「用於宣告的關鍵字」。一般地,使用者可以閱讀函式的宣告,但是看不到函式的定義。儘管在大多數教科書中內聯函式的宣告、定義體前面都加了inline關鍵字,但我認為inline不應該出現在函式的宣告中。這個細節雖然不會影響函式的功能,但是體現了高質量c++/c程式設計風格的乙個基本原則:宣告與定義不可混為一談,使用者沒有必要、也不應該知道函式是否需要內聯。

mysql 內聯函式 Kotlin內聯函式

內聯函式使用關鍵字內聯宣告,內聯函式的使用增強了高階函式的效能。內聯函式告訴編譯器將引數和函式複製到呼叫站點。虛函式或區域性函式不能宣告為內聯。以下是內聯函式內部不支援的一些表示式和宣告 區域性類宣告 內部巢狀類的宣告 函式表示式 宣告區域性函式 區域性可選引數的預設值 讓我們看一下內聯函式的基本示...

虛函式的實現機制

將函式宣告為virtual時,在背後發生了什麼呢?編譯器在編譯的時候,發現animal類中有虛函式,此時編譯器會為每個包含虛函式的類建立乙個虛表 即vtable 該表是乙個一維陣列,在這個陣列中存放每個虛函式的位址。對於例1 2的程式,animal和fish類都包含了乙個虛函式breathe 因此編...

虛函式的實現機制

一 虛函式表 對c 了解的人都應該知道虛函式 virtual function 是通過一張虛函式表 virtual table 來實現的。簡稱為v table。在這個表中,主要是乙個類的虛函式的位址表,這張表解決了繼承 覆蓋的問題,保證真實反應實際的函式。這樣,在有虛函式的類的例項中這個表被分配在了...