宏定義尤其是帶參數(shù)的宏定義,特別容易出現(xiàn)一些隱藏問題,因?yàn)楹甓x在預(yù)處理階段是按照定義原封不動的進(jìn)行展開,此時(shí)如果展開之后涉及到運(yùn)算符優(yōu)先級的問題,那么隱藏bug就此出現(xiàn)。
這里我先列舉一個(gè)簡單的例子,然后歸納下帶參數(shù)宏定義對于括號使用的一些說明。
1.構(gòu)造帶有隱藏bug的宏定義
下面定義兩個(gè)帶參數(shù)宏,MUL_TWO是將兩個(gè)數(shù)進(jìn)行相乘,MUL_THREE是將三個(gè)數(shù)進(jìn)行相乘。
#defineMUL_TWO(val1,val2)(val1*val2) #defineMUL_THREE(x,y,z)(MUL_TWO(x,y)*z)
比如我這里計(jì)算2 * 3 * 4的運(yùn)算結(jié)果,那么只需調(diào)用宏MUL_THREE(2, 3, 4)就可得到計(jì)算結(jié)果為:24,計(jì)算結(jié)果是正確的。但是如果將MUL_THREE(2, 3, 4)修改為MUL_THREE(1+1, 1+2, 1+3),此時(shí)的運(yùn)算結(jié)果又是多少呢,很簡單,我們將這個(gè)宏進(jìn)行展開,展開的過程如下所示:
MUL_THREE(1+1,1+2,1+3)=>(MUL_TWO(1+1,1+2)*1+3) (MUL_TWO(1+1,1+2)*1+3)=>((1+1*1+2)*1+3)
然后我們計(jì)算下,得出結(jié)果是7,是不是計(jì)算錯(cuò)誤了。
2.改造上述宏定義
這里的宏定義還是比較簡單的,并且大多數(shù)的小伙伴應(yīng)該都知道在定義帶參數(shù)的宏時(shí),參數(shù)需要使用括號括起來,那么我們改造下上述的宏,改造結(jié)果如下所示:
#defineMUL_TWO(val1,val2)((val1)*(val2)) #defineMUL_THREE(x,y,z)(MUL_TWO(x,y)*z)
此時(shí)再來對MUL_THREE(1+1, 1+2, 1+3)進(jìn)行展開,展開的過程如下所示:
MUL_THREE(1+1,1+2,1+3)=>(MUL_TWO(1+1,1+2)*1+3) (MUL_TWO(1+1,1+2)*1+3)=>(((1+1)*(1+2))*1+3)
然后我們計(jì)算下,得出結(jié)果是9,計(jì)算結(jié)果還是有問題。仔細(xì)檢查下宏定義,原來是對MUL_THREE宏的z沒有用括號括起來,這個(gè)問題也是比較容易犯的,修改好之后的宏如下所示:
#defineMUL_TWO(val1,val2)((val1)*(val2)) #defineMUL_THREE(x,y,z)(MUL_TWO(x,y)*(z))
此時(shí)再來對MUL_THREE(1+1, 1+2, 1+3)進(jìn)行展開,展開的過程如下所示:
MUL_THREE(1+1,1+2,1+3)=>(MUL_TWO(1+1,1+2)*(1+3)) (MUL_TWO(1+1,1+2)*(1+3))=>(((1+1)*(1+2))*(1+3))
此時(shí)的計(jì)算結(jié)果就是沒問題的了。
這里我再提個(gè)問題,為什么你在MUL_THREE宏中,只使用括號括起了z,為啥x和y你不同等對待,確實(shí)哈,如果對于不是很熟悉的小伙伴,可能看到我說的情況,會毫不猶豫的也對x和y進(jìn)行同樣的保護(hù);也有的小伙伴看到我說的這個(gè)情況可能腦子里面就暈了。
3.帶參數(shù)宏定義對于括號使用的一些說明
其實(shí)不對x和y做保護(hù)是有一個(gè)前提的,那就是你所定義的每一個(gè)宏定義都要確保對在當(dāng)前宏中使用到的參數(shù)用括號進(jìn)行保護(hù)。不知道各位明白我的意思不,不明白的話,看看我下面的總結(jié)吧。
帶參數(shù)宏定義,對于括號何時(shí)使用的總結(jié):
(1).帶參數(shù)宏定義,如果參數(shù)在當(dāng)前的宏中有進(jìn)行運(yùn)算,那么必須對該參數(shù)使用括號括起來(類似例子中MUL_THREE里面的z,MUL_TWO里面的val1和val2);
(2).帶參數(shù)宏定義,如果參數(shù)沒有在當(dāng)前的宏中有進(jìn)行運(yùn)算,而是直接當(dāng)成參數(shù)傳遞給其他的宏,那么該參數(shù)是不用使用括號進(jìn)行保護(hù)的(類似例子中MUL_THREE里面的x和y)。
對于上面的總結(jié)第(2)點(diǎn),能夠?qū)鬟f給其他宏的參數(shù)不進(jìn)行括號保護(hù)是因?yàn)榭偨Y(jié)的第(1)點(diǎn)已經(jīng)對宏做了一個(gè)規(guī)定,只要所有的宏定義都按照第(1)點(diǎn)進(jìn)行書寫,那么第(2)點(diǎn)自然也就不會出什么問題。
審核編輯:劉清
-
C語言
+關(guān)注
關(guān)注
180文章
7598瀏覽量
136183 -
Mul
+關(guān)注
關(guān)注
0文章
5瀏覽量
7952 -
宏定義
+關(guān)注
關(guān)注
0文章
50瀏覽量
9001
原文標(biāo)題:C語言-帶參數(shù)宏定義易出現(xiàn)的隱藏bug和定義方式歸納
文章出處:【微信號:嵌入式那些事,微信公眾號:嵌入式那些事】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論