色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

C語言開發如何將錯誤扼殺在編譯階段

嵌入式軟件實戰派 ? 來源:嵌入式軟件實戰派 ? 2023-10-17 16:44 ? 次閱讀
你有沒有想過,C語言一些簡單的語法規則,可以做出很巧妙的方法。 舉個例子,C語言的數組長度是不允許是負數的,當然常識中數組長度為負數好像也沒什么意義。 例如int arr[1];是對的,而int arr[-1];是錯的。 這個規則很簡單,也很容易理解,當然也不會引人關注。 但是呢,我說可以用這個語法規則做C語言assert斷言錯誤檢查,你信么?優秀的程序員,一般都是想盡一切辦法將程序的錯誤盡可能地被攔截在運行之前,即編譯階段和預編譯階段的,而不是流出到運行階段,更不是發生在用戶手里的產品中。對于預編譯階段的錯誤攔截,比較簡單,通過#if#error等預編譯指令就可以做到,例如1. FreeRTOS中的Priority檢查,用戶必須將優先級定義大于或等于1,否則就報錯
#ifconfigMAX_PRIORITIES
  #errorconfigMAX_PRIORITIESmustbedefinedtobegreaterthanorequalto1.
#endif
這是因為,程序設計里如果遇到configMAX_PRIORITIES < 1的情況,可能會導致更嚴重的錯誤。 所以這種在預編譯階段攔截了這個錯誤,是很有作用的2. FreeRTOS中的運行時狀態獲取函數,必須依賴于configUSE_TRACE_FACILITY的定義
void vTaskGetRunTimeStats( char *pcWriteBuffer )
{
TaskStatus_t *pxTaskStatusArray;
UBaseType_t uxArraySize, x;
uint32_t ulTotalTime, ulStatsAsPercentage;
#if( configUSE_TRACE_FACILITY != 1 )
{
    #error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats().
}
#endif

因為,這個函數很依賴其他其他的函數實現或者資源定義,那么這個configUSE_TRACE_FACILITY管理了這些

3. 版本檢查,如果你設計一個比較通用的功能,可以用到很多項目中去,為了方便管理和迭代更新,就要對這個功能模塊做版本定義。那么不同版本之間就存在差異,可能存在不兼容的情況,此時就可以用預編譯指令做這種兼容的檢查
#if (XXX_VER < 0x201)
    #error "This version of XXX is too low!"
#endif
通過預編譯指令來檢查錯誤是很有限的,因為預編譯指令能檢查的是立即數和一些邏輯關系。于是,我們還要考慮編譯階段的錯誤檢查,即對在編譯階段產生的結果做檢查。例如,unsigned long或者void*的長度檢查即sizeof(unsignedlong)sizeof(void*)的值,就必須在編譯階段由于unsigned longvoid*的長度在不同芯片架構上可能存在差異,如果你的程序依賴這個類型的長度,那必須要檢查其長度是否為你設計的那樣。像這種#if sizeof(unsigned long) == 4是不正確的做法,因為預編譯無法計算sizeof(unsigned long)那么有沒有一種情況能確保sizeof(unsigned long)的值是4才不出錯呢?也許你會想到一個叫assert的東西,例如FreeRTOS里面定義的
#defineconfigASSERT(x)if((x)==0){ taskDISABLE_INTERRUPTS();for(;;);}
既可以這樣使用configASSERT(sizeof(unsigned long) == 4),如果sizeof(unsignedlong) == 4,那么程序是“靜悄悄”的,當做啥事都沒發生,但是如果sizeof(unsigned long) == 8,那么程序就會進入for( ;; );無法自拔。但是這種做法是運行階段的,必須要在程序已經集成好并讓其在實際環境中運行才能發現這種錯誤,排查起來成本還是有點高。那么有沒有一種辦法可以讓其扼殺在編譯階段呢?答案是有的,像C++11和C11就支持這種assert了,名叫STATIC_ASSERT,需要包含頭文件assert.h。但是,如果我還沒用到C11,也想用這種STATIC_ASSERT呢,有沒有辦法自己實現一個?答案也是可以的,需要想個竅門,例如從數組的長度入手。int arr[1];這種定義是沒有問題的,但int arr[-1];卻是會引起編譯器報錯的,我們就可以基于這種東西做文章了,即將數組長度換成檢查條件COND,即如果COND為TRUE就不報錯,為FALSE就報錯通過一頓反復嘗試,搞成這樣或許就可以了
int arr[(!!(COND))*2-1];
這里(!!(COND))*2-1沒有一個符號是多余的,簡單解釋下:1.(COND),這里加了一層括號,防止COND是個比較復雜的表達式,可能引發未知的優先級問題;2.(!!(COND)),這里有兩個感嘆號,即邏輯取反再取反。也許你會覺得有點奇怪,!!TRUE不就是TURE嗎,!!FALSE也是FALSE啊,雙層取反是不是有點多余。那你就要認真思考下TRUE和FALSE的定義了,C語言中的FALSE是0,而非0是TRUE,這個非0就有很多發揮空間了,例如整數100,也是TRUE,但是!!100就會變成1,這里的(!!(COND))就是讓其結果變成0或者1,而不是其他數

3.通過2的解釋,就很容易理解(!!(COND))*2-1這可以保證這個結果是1或者-1,而不存在其他數值。因為,我們的目的要的是int arr[1];或者int arr[-1];即可。

定義一個數組用在程序中間好像用起來沒那么友好,可以換成
typedef int arr[(!!(COND))*2-1];
為了還能看到多一點點錯誤信息,還可以將其定義成宏,并帶多一個參數,這就成了這樣
#defineSTATIC_ASSERT(COND,MSG)typedefchar static_assertion_##MSG[(!!(COND))*2-1]
在這個基礎上再搞定其他的,就可以這樣了
// token pasting madness:
#defineCOMPILE_TIME_ASSERT3(X,L) STATIC_ASSERT(X,static_assertion_at_line_##L)
#define COMPILE_TIME_ASSERT2(X,L) COMPILE_TIME_ASSERT3(X,L)
#define COMPILE_TIME_ASSERT(X)    COMPILE_TIME_ASSERT2(X,__LINE__)
接著,判斷sizeof(unsigned long) 是否為4,就可以這樣
STATIC_ASSERT(sizeof(unsignedlong)==4,unsigned_long_size_is_not_4_error);

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

    關注

    180

    文章

    7608

    瀏覽量

    137200
  • C++
    C++
    +關注

    關注

    22

    文章

    2112

    瀏覽量

    73736
  • 編譯
    +關注

    關注

    0

    文章

    660

    瀏覽量

    32920

原文標題:C語言開發如何將錯誤扼殺在編譯階段

文章出處:【微信號:embedded_sw,微信公眾號:嵌入式軟件實戰派】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    幾款C語言編譯器推薦

    一些剛開始接觸C語言編譯的網友想下載一款C語言編譯器來使用,不過,網絡上有不少
    發表于 09-05 09:19 ?1w次閱讀

    C語言編譯鏈接過程

    ? C語言編譯鏈接過程要把我們編寫的一個C程序源代碼轉換成可以在硬件上運行的程序(可執行代碼),需要進行編譯和鏈接。
    的頭像 發表于 08-21 10:06 ?2647次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>的<b class='flag-5'>編譯</b>鏈接過程

    Rust語言錯誤處理的機制

    在Rust語言中,錯誤處理是一項非常重要的任務。由于Rust語言采用靜態類型檢查,在編譯時就能發現很多潛在的錯誤,這使得程序員能夠更加自信和
    的頭像 發表于 09-19 14:54 ?1443次閱讀

    C語言編譯過程是怎樣的

    C語言C語言編譯過程,各過程作用預處理階段源碼文件
    發表于 10-27 09:00

    如何將高級C語言編譯成機器碼

    器各個階段做得事情,這里不做詳細介紹,感興趣的粉絲可以自己找資料學習。C語言編譯器有很多種,在我們芯片行業,主要有GCC和LLVM。下面框圖簡單的描述了一個CPU
    發表于 06-01 16:53

    C語言編譯過程中的錯誤分析

      語言的最大特點是:功能強、使用方便靈活。C編譯的程序對語法檢查并不象其它高級語言那么嚴格,這就給編程人員留下“靈活的余地”,但還是由于這個靈活給程序的調試
    發表于 09-11 11:43 ?1338次閱讀

    C語言編程時常犯的18種錯誤

    C語言的最大特點是:功能強、使用方便靈活。C編譯的程序對語法檢查并不象其它高級語言那么嚴格,這就給編程人員留下“靈活的余地”,但還是由于這個
    的頭像 發表于 02-27 14:51 ?6318次閱讀

    如何將C源代碼從MPLAB C18編譯器移植到MPLAB XC8C編譯器的詳細概述

    本文檔介紹了針對PIC18 MCU的MPLAB? C編譯器(以前的說法,本文檔稱為MPLAB C18)與MPLAB XC8 C編譯器間的差異
    發表于 06-07 09:28 ?30次下載
    <b class='flag-5'>如何將</b><b class='flag-5'>C</b>源代碼從MPLAB <b class='flag-5'>C</b>18<b class='flag-5'>編譯</b>器移植到MPLAB XC8<b class='flag-5'>C</b><b class='flag-5'>編譯</b>器的詳細概述

    C語言編譯器中有哪些錯誤信息詳細中英文對比

    本文檔的主要內容詳細介紹的是C語言編譯器中有哪些錯誤信息詳細中英文對比詳細資料免費下載。
    發表于 11-09 17:43 ?13次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>編譯</b>器中有哪些<b class='flag-5'>錯誤</b>信息詳細中英文對比

    C語言里extern "C" 是什么意思?

    通常用于C++和C混合編程的時候,為了防止C++的編譯在編譯C文件的時候出現
    的頭像 發表于 09-07 11:09 ?6955次閱讀

    解析C語言編譯過程中所做的工作

    過程是有幫助的。而且清楚的了解編譯鏈接過程還對我們在編程時定位錯誤,以及編程時盡量調動編譯器的檢測錯誤會有很大的幫助的。
    的頭像 發表于 06-27 10:21 ?3198次閱讀
    解析<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>編譯</b>過程中所做的工作

    VScode編譯器如何配置C/C++編譯環境

    昨天有伙伴私信我,為什么我用C語言寫的hello world幾行代碼,在編譯器里面報錯了呢?
    的頭像 發表于 03-16 08:38 ?5654次閱讀

    c語言代碼錯誤怎么找

    ,它們通常是由于C語言編寫規則被打破所引起的。實際上,C編譯器會提供非常詳細的錯誤消息,告訴我們在哪個地方發生了
    的頭像 發表于 11-24 10:05 ?4215次閱讀

    為什么C語言要進行編譯

    為什么我們編寫的C語言要進行編譯?什么是編譯編譯時發生了什么? 機器無法理解我們編寫的C
    的頭像 發表于 11-24 15:47 ?1391次閱讀
    為什么<b class='flag-5'>C</b><b class='flag-5'>語言</b>要進行<b class='flag-5'>編譯</b>

    C語言關鍵字分別發生在哪個階段

    以下C語言關鍵字,分別發生在哪個階段? 第一個,define。 首先得糾正一下,define 并不是C語言里面的關鍵字,即使加了井號,也不是
    的頭像 發表于 11-24 10:31 ?208次閱讀
    主站蜘蛛池模板: 精品无码一区二区三区不卡| 孕妇泬出白浆18P| 日本美女搞基视频| 亚洲精品喷白浆在线观看| 最近日本MV字幕免费观看在线| AV无码久久无遮挡国产麻豆| 国产午夜精品久久久久九九| 免费视频精品38| 亚洲高清无码在线 视频| A级毛片高清免费网站不卡| 国产真实乱对白精彩| 日本十八禁无遮拦啪啪漫画| 真实处破女全过程完免费观看| 国产精品99亚发布| 男人天堂黄色| 伊人久久大香线蕉资源| 国产精品v片在线观看不卡| 欧美精品色视频| 影音先锋色小姐| 国产色情短视频在线网站| 欧美性暴力变态xxxx| 最新高清无码专区| 韩国和日本免费不卡在线| 天堂so导航| 处初女处夜情视频在线播放| 理论片午午伦夜理片2021| 性xxx在线观看| 囯产免费久久久久久国产免费| 牛牛免费视频| 中文字幕在线播放视频| 久久 这里只精品 免费| 亚洲精品国产精品麻豆99| 国产人妻777人伦精品HD| 网友自拍成人在线视频| 国产哺乳期奶水avav| 入禽太深免费高清在线观看5| videos gratis欧美另类| 欧美激情久久久久久久大片| 91亚洲 欧美 国产 制服 动漫| 久久久免费观看| 在线看片av以及毛片|