在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

帶參數宏定義易出現的隱藏bug和定義方式歸納

嵌入式那些事 ? 來源:嵌入式那些事 ? 2023-10-20 15:26 ? 次閱讀

宏定義尤其是帶參數的宏定義,特別容易出現一些隱藏問題,因為宏定義在預處理階段是按照定義原封不動的進行展開,此時如果展開之后涉及到運算符優先級的問題,那么隱藏bug就此出現。

這里我先列舉一個簡單的例子,然后歸納下帶參數宏定義對于括號使用的一些說明。

1.構造帶有隱藏bug的宏定義

下面定義兩個帶參數宏,MUL_TWO是將兩個數進行相乘,MUL_THREE是將三個數進行相乘。

#defineMUL_TWO(val1,val2)(val1*val2)
#defineMUL_THREE(x,y,z)(MUL_TWO(x,y)*z)

比如我這里計算2 * 3 * 4的運算結果,那么只需調用宏MUL_THREE(2, 3, 4)就可得到計算結果為:24,計算結果是正確的。但是如果將MUL_THREE(2, 3, 4)修改為MUL_THREE(1+1, 1+2, 1+3),此時的運算結果又是多少呢,很簡單,我們將這個宏進行展開,展開的過程如下所示:

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)

然后我們計算下,得出結果是7,是不是計算錯誤了。

2.改造上述宏定義

這里的宏定義還是比較簡單的,并且大多數的小伙伴應該都知道在定義帶參數的宏時,參數需要使用括號括起來,那么我們改造下上述的宏,改造結果如下所示:

#defineMUL_TWO(val1,val2)((val1)*(val2))
#defineMUL_THREE(x,y,z)(MUL_TWO(x,y)*z)

此時再來對MUL_THREE(1+1, 1+2, 1+3)進行展開,展開的過程如下所示:

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)

然后我們計算下,得出結果是9,計算結果還是有問題。仔細檢查下宏定義,原來是對MUL_THREE宏的z沒有用括號括起來,這個問題也是比較容易犯的,修改好之后的宏如下所示:

#defineMUL_TWO(val1,val2)((val1)*(val2))
#defineMUL_THREE(x,y,z)(MUL_TWO(x,y)*(z))

此時再來對MUL_THREE(1+1, 1+2, 1+3)進行展開,展開的過程如下所示:

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))

此時的計算結果就是沒問題的了。

這里我再提個問題,為什么你在MUL_THREE宏中,只使用括號括起了z,為啥x和y你不同等對待,確實哈,如果對于不是很熟悉的小伙伴,可能看到我說的情況,會毫不猶豫的也對x和y進行同樣的保護;也有的小伙伴看到我說的這個情況可能腦子里面就暈了。

3.帶參數宏定義對于括號使用的一些說明

其實不對x和y做保護是有一個前提的,那就是你所定義的每一個宏定義都要確保對在當前宏中使用到的參數用括號進行保護。不知道各位明白我的意思不,不明白的話,看看我下面的總結吧。

帶參數宏定義,對于括號何時使用的總結:

(1).帶參數宏定義,如果參數在當前的宏中有進行運算,那么必須對該參數使用括號括起來(類似例子中MUL_THREE里面的z,MUL_TWO里面的val1和val2);

(2).帶參數宏定義,如果參數沒有在當前的宏中有進行運算,而是直接當成參數傳遞給其他的宏,那么該參數是不用使用括號進行保護的(類似例子中MUL_THREE里面的x和y)。

對于上面的總結第(2)點,能夠對傳遞給其他宏的參數不進行括號保護是因為總結的第(1)點已經對宏做了一個規定,只要所有的宏定義都按照第(1)點進行書寫,那么第(2)點自然也就不會出什么問題。







審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7614

    瀏覽量

    137724
  • Mul
    Mul
    +關注

    關注

    0

    文章

    5

    瀏覽量

    7965
  • 宏定義
    +關注

    關注

    0

    文章

    51

    瀏覽量

    9051

原文標題:C語言-帶參數宏定義易出現的隱藏bug和定義方式歸納

文章出處:【微信號:嵌入式那些事,微信公眾號:嵌入式那些事】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    C語言定義使用技巧

    寫好C語言,漂亮的定義很重要,使用定義可以防止出錯,提高可移植性,可讀性,方便性等等。下面列舉一些成熟軟件中常用的
    發表于 07-29 09:35 ?1135次閱讀

    C語言定義與枚舉類型知識

    定義的標識符不占內存,只是一個臨時的符號,預編譯后這個符號就不存在了。在簡單的程序使用參數定義可完成函數調用的功能,又能減少系統開銷,
    發表于 10-11 17:34 ?1649次閱讀

    C語言中常用的定義

    寫好C語言,漂亮的定義很重要,使用定義可以防止出錯,提高可移植性,可讀性,方便性等等。下面列舉一些成熟軟件中常用的
    發表于 10-18 10:05 ?1742次閱讀

    詳細聊聊container_of這個定義

    大家周末好,我是bug菌~ 今天主要是跟大家詳細聊聊container_of這個定義,非常經典的,只是一直沒有抽時間細細品味,今天就跟大家一起來看看有何神奇之處。
    的頭像 發表于 11-13 09:45 ?747次閱讀

    請問FLASH 的定義是如何定義的?為什么?

    ,"ramfuncs");#pragma CODE_SECTION(OffsetISR,"ramfuncs");#endif但是這個FLASH 的定義不知在哪里進行
    發表于 06-11 07:42

    C語言定義使用技巧

    寫好C語言,漂亮的定義很重要,使用定義可以防止出錯,提高可移植性,可讀性,方便性 等等。下面列舉一些成熟軟件中常用得
    發表于 11-13 12:04 ?36次下載

    內聯函數和定義的區別介紹

    定義是C語言提供的三種預處理功能的其中一種,這三種預處理包括:定義、文件包含、條件編譯。定義
    發表于 12-15 15:33 ?2354次閱讀
    內聯函數和<b class='flag-5'>宏</b><b class='flag-5'>定義</b>的區別介紹

    不帶參數定義是什么?不帶參數定義的資料介紹詳細過程概述

    c語言中有一個定義,其中有一類就是不帶參數定義
    發表于 09-04 15:38 ?5次下載

    當使用參數調用時,會將參數替換為主體

    在大多數定義示例中,每次出現參數名稱都帶有括號,并且另一對括號通常會包圍整個
    的頭像 發表于 11-16 16:41 ?2383次閱讀

    對于定義與重復定義的問題

    對于定義與重復定義的問題
    發表于 11-29 18:21 ?1次下載
    對于<b class='flag-5'>宏</b><b class='flag-5'>定義</b>與重復<b class='flag-5'>定義</b>的問題

    C語言定義--單片機中斷

    在單片機中斷中可以使用定義代替函數,減小系統運行時間。1.參數定義的優點:用
    發表于 01-13 12:52 ?6次下載
    C語言<b class='flag-5'>宏</b><b class='flag-5'>定義</b>--單片機中斷

    C語言中的定義

    #define命令是C語言中的一個定義命令,它用來將一個標識符定義為一個字符串,該標識符被稱為名,被定義的字符串稱為替換文本。命令有兩種
    的頭像 發表于 09-28 16:05 ?3514次閱讀
    C語言中的<b class='flag-5'>宏</b><b class='flag-5'>定義</b>

    c語言定義可以嵌套嗎?

    某些代碼或表達式替換為指定的字符串,從而使程序更加靈活和可讀性更高。定義的語法形式為: #define 名(參數列表) 體 其中,
    的頭像 發表于 09-04 17:38 ?3281次閱讀

    c語言參數定義

    c語言參數定義? C語言定義是一種替換機制
    的頭像 發表于 09-04 17:45 ?2495次閱讀

    define定義

    define定義 以#號開頭的都是編譯預處理指令,它們不是C語言的成分,但是C程序離不開它們,#define用來定義一個,程序在預處理階段將用define
    的頭像 發表于 11-24 15:35 ?946次閱讀
    主站蜘蛛池模板: 奇米影视狠狠 | xxx86日本人| 国产黄色大全 | 88xx成人永久免费观看 | 免费视频不卡一区二区三区 | 亚洲综合激情九月婷婷 | 欧美成人三级网站 | 精品久久久久久婷婷 | 天天干天操 | 思思99re66在线精品免费观看 | yy4080午夜理论一级毛片 | 国产亚洲精品久久久久久午夜 | 日本口工全彩无遮拦漫画大 | 清朝荒淫牲艳史在线播放 | 在线免费视频 | 国产网红精品 | 亚洲性久久久影院 | 午夜影视剧场 | 男人的天堂色偷偷之色偷偷 | 又污又黄的网站 | 1000又爽又黄禁片 | 日本三级黄色网址 | 国产精品久久精品福利网站 | 欧美性xx18一19 | 免费一级视频在线播放 | 国产 高清 在线 | 一区二区三区四区精品 | 中国一级特黄真人毛片免费看 | 久色国产 | 五月天婷婷网址 | 五月婷婷色丁香 | 丁香婷婷综合网 | 国产精品毛片在线大全 | 五月天婷婷激情 | 国产二区三区 | 51精品视频免费国产专区 | 天天操天天玩 | 日本亚洲欧美国产日韩ay高清 | 欧美一级特黄高清免费 | 年轻的护士3在线观看 | 久久精品隔壁老王影院 |