C++淺析內(nèi)聯(lián)函數(shù)的使用
一. 概念
以inline修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時(shí)C++編譯器會(huì)在調(diào)用內(nèi)聯(lián)函數(shù)的地方展開(kāi),沒(méi)有函數(shù)壓棧的開(kāi)銷(xiāo), 內(nèi)聯(lián)函數(shù)提升程序運(yùn)行的效率。
在C++里為了提高效率使用內(nèi)聯(lián)函數(shù),可是我們會(huì)發(fā)現(xiàn)在C語(yǔ)言里面已經(jīng)有了宏,也可以處理關(guān)于這個(gè)效率的問(wèn)題,那為什么還會(huì)出現(xiàn)內(nèi)聯(lián)函數(shù)呢?
當(dāng)我們要寫(xiě)一個(gè)Add的宏時(shí):
#define Add(x, y) ((x) + (y))
但是也有人可能會(huì)寫(xiě)錯(cuò),出現(xiàn)下面這些情況,比如:
#define Add(x, y) return x + y ; #define Add(x, y) return (x + y); #define Add(x, y) return (x + y) #define Add(x, y) x + y #define Add(x, y) x + y; #define Add(x, y) (x + y); #define Add(x, y) (x + y)
以上這些都是有可能會(huì)出現(xiàn)的情況,既然這么容易寫(xiě)錯(cuò),于是乎C++就出現(xiàn)了內(nèi)聯(lián)函數(shù),就是為了解決宏函數(shù)晦澀難懂,容易寫(xiě)錯(cuò)的問(wèn)題
那么如何查看內(nèi)聯(lián)函數(shù)呢?
我們知道宏是不支持調(diào)試的,但是內(nèi)聯(lián)函數(shù)是支持調(diào)試的,那內(nèi)聯(lián)函數(shù)怎么支持調(diào)試的呢?其實(shí)內(nèi)聯(lián)函數(shù)在debug版本下是不會(huì)展開(kāi)的,如圖:
但是release版本下又看不到匯編代碼,為了能查看內(nèi)聯(lián)函數(shù),我們需要更改一些設(shè)置提高優(yōu)化等級(jí),在debug模式下,需要對(duì)編譯器進(jìn)行設(shè)置,否則不會(huì)展開(kāi),因?yàn)閐ebug模式下,編譯器默認(rèn)不會(huì)對(duì)代碼進(jìn)行優(yōu)化,以下給出vs2019的設(shè)置方式,如下圖:(這里由于疏忽忘記在函數(shù)前加上inline,記得加上并重新編譯以后在調(diào)試狀態(tài)下轉(zhuǎn)到反匯編查看)
這些配置好了以后再次查看匯編代碼:
我們就會(huì)發(fā)現(xiàn)這里不再call函數(shù)了,說(shuō)明沒(méi)有建立函數(shù)棧幀,而是直接展開(kāi)了,inline起作用了這里
二. 特性
- inline是一種以空間換時(shí)間的做法,省去調(diào)用函數(shù)額開(kāi)銷(xiāo)(建立棧幀)。所以代碼很長(zhǎng)或者有循環(huán)/遞歸的函數(shù)不適宜使用作為內(nèi)聯(lián)函數(shù)。(一般十行左右的代碼使用)
- inline對(duì)于編譯器而言只是一個(gè)建議,編譯器會(huì)自動(dòng)優(yōu)化,如果定義為inline的函數(shù)體內(nèi)有循環(huán)/遞歸或者代碼太長(zhǎng)等等,編譯器優(yōu)化時(shí)會(huì)忽略掉內(nèi)聯(lián)。
- inline不建議聲明和定義分離,分離會(huì)導(dǎo)致鏈接錯(cuò)誤。因?yàn)閕nline被展開(kāi),就沒(méi)有函數(shù)地址了,鏈接就會(huì)找不到。
聲明和定義分離以后會(huì)報(bào)鏈接錯(cuò)誤:
回顧:
宏的優(yōu)缺點(diǎn)?
優(yōu)點(diǎn):
1.增強(qiáng)代碼的復(fù)用性。
2.提高性能。
缺點(diǎn):
1.不方便調(diào)試宏。(因?yàn)轭A(yù)編譯階段進(jìn)行了替換)
2.導(dǎo)致代碼可讀性差,可維護(hù)性差,容易誤用。
3.沒(méi)有類(lèi)型安全的檢查 。
擴(kuò)展:
C++有哪些技術(shù)替代宏?
1. 常量定義 換用const
2. 函數(shù)定義 換用內(nèi)聯(lián)函數(shù)
到此這篇關(guān)于C++淺析內(nèi)聯(lián)函數(shù)的使用的文章就介紹到這了,更多相關(guān)C++內(nèi)聯(lián)函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++初階之list的模擬實(shí)現(xiàn)過(guò)程詳解
在C++中我們經(jīng)常使用STL,那個(gè)在那些我們常用的數(shù)據(jù)結(jié)構(gòu)vector,list的背后,又是如何實(shí)現(xiàn)的呢?這篇文章主要給大家介紹了關(guān)于C++初階之list的模擬實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2021-08-08通過(guò)“回文字算法”復(fù)習(xí)C++語(yǔ)言
這篇文章主要介紹了通過(guò)“回文字算法”復(fù)習(xí)C++語(yǔ)言的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10C++封裝成DLL并調(diào)用的實(shí)現(xiàn)
本文主要介紹了C++封裝成DLL并調(diào)用的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03一文教你Qt如何操作SQLite數(shù)據(jù)庫(kù)
Sqlite 數(shù)據(jù)庫(kù)作為 Qt 項(xiàng)目開(kāi)發(fā)中經(jīng)常使用的一個(gè)輕量級(jí)的數(shù)據(jù)庫(kù),可以說(shuō)是兼容性相對(duì)比較好的數(shù)據(jù)庫(kù)之一。本文為大家介紹了Qt操作SQLite數(shù)據(jù)庫(kù)的具體方法,希望對(duì)大家有所幫助2023-03-03c++ 單線程實(shí)現(xiàn)同時(shí)監(jiān)聽(tīng)多個(gè)端口
這篇文章主要介紹了c++ 單線程實(shí)現(xiàn)同時(shí)監(jiān)聽(tīng)多個(gè)端口的方法,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下2021-03-03C語(yǔ)言實(shí)現(xiàn)帶頭雙向循環(huán)鏈表的接口
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)帶頭雙向循環(huán)鏈表的接口,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10C語(yǔ)言基礎(chǔ)知識(shí)變量的作用域和存儲(chǔ)方式詳細(xì)介紹
這篇文章主要介紹了C語(yǔ)言基礎(chǔ)知識(shí)變量的作用域和存儲(chǔ)方式詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2017-01-01