chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語(yǔ)言開(kāi)發(fā)如何將錯(cuò)誤扼殺在編譯階段

嵌入式軟件實(shí)戰(zhàn)派 ? 來(lái)源:嵌入式軟件實(shí)戰(zhàn)派 ? 2023-10-17 16:44 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

你有沒(méi)有想過(guò),C語(yǔ)言一些簡(jiǎn)單的語(yǔ)法規(guī)則,可以做出很巧妙的方法。 舉個(gè)例子,C語(yǔ)言的數(shù)組長(zhǎng)度是不允許是負(fù)數(shù)的,當(dāng)然常識(shí)中數(shù)組長(zhǎng)度為負(fù)數(shù)好像也沒(méi)什么意義。 例如int arr[1];是對(duì)的,而int arr[-1];是錯(cuò)的。 這個(gè)規(guī)則很簡(jiǎn)單,也很容易理解,當(dāng)然也不會(huì)引人關(guān)注。 但是呢,我說(shuō)可以用這個(gè)語(yǔ)法規(guī)則做C語(yǔ)言assert斷言錯(cuò)誤檢查,你信么?優(yōu)秀的程序員,一般都是想盡一切辦法將程序的錯(cuò)誤盡可能地被攔截在運(yùn)行之前,即編譯階段和預(yù)編譯階段的,而不是流出到運(yùn)行階段,更不是發(fā)生在用戶(hù)手里的產(chǎn)品中。對(duì)于預(yù)編譯階段的錯(cuò)誤攔截,比較簡(jiǎn)單,通過(guò)#if#error等預(yù)編譯指令就可以做到,例如1. FreeRTOS中的Priority檢查,用戶(hù)必須將優(yōu)先級(jí)定義大于或等于1,否則就報(bào)錯(cuò)
#ifconfigMAX_PRIORITIES
  #errorconfigMAX_PRIORITIESmustbedefinedtobegreaterthanorequalto1.
#endif
這是因?yàn)?,程序設(shè)計(jì)里如果遇到configMAX_PRIORITIES < 1的情況,可能會(huì)導(dǎo)致更嚴(yán)重的錯(cuò)誤。 所以這種在預(yù)編譯階段攔截了這個(gè)錯(cuò)誤,是很有作用的2. FreeRTOS中的運(yùn)行時(shí)狀態(tài)獲取函數(shù),必須依賴(lài)于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

因?yàn)?,這個(gè)函數(shù)很依賴(lài)其他其他的函數(shù)實(shí)現(xiàn)或者資源定義,那么這個(gè)configUSE_TRACE_FACILITY管理了這些

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

3.通過(guò)2的解釋?zhuān)秃苋菀桌斫?/span>(!!(COND))*2-1這可以保證這個(gè)結(jié)果是1或者-1,而不存在其他數(shù)值。因?yàn)椋覀兊哪康囊氖?span style="font-family:'Microsoft YaHei';letter-spacing:.578px;background-color:rgb(214,214,214);">int arr[1];或者int arr[-1];即可。

定義一個(gè)數(shù)組用在程序中間好像用起來(lái)沒(méi)那么友好,可以換成
typedef int arr[(!!(COND))*2-1];
為了還能看到多一點(diǎn)點(diǎn)錯(cuò)誤信息,還可以將其定義成宏,并帶多一個(gè)參數(shù),這就成了這樣
#defineSTATIC_ASSERT(COND,MSG)typedefchar static_assertion_##MSG[(!!(COND))*2-1]
在這個(gè)基礎(chǔ)上再搞定其他的,就可以這樣了
// 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);

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    183

    文章

    7634

    瀏覽量

    143880
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2120

    瀏覽量

    76446
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    682

    瀏覽量

    34766

原文標(biāo)題:C語(yǔ)言開(kāi)發(fā)如何將錯(cuò)誤扼殺在編譯階段

文章出處:【微信號(hào):embedded_sw,微信公眾號(hào):嵌入式軟件實(shí)戰(zhàn)派】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    幾款C語(yǔ)言編譯器推薦

    一些剛開(kāi)始接觸C語(yǔ)言編譯的網(wǎng)友想下載一款C語(yǔ)言編譯器來(lái)使用,不過(guò),網(wǎng)絡(luò)上有不少
    發(fā)表于 09-05 09:19 ?1.1w次閱讀

    C語(yǔ)言編譯鏈接過(guò)程

    ? C語(yǔ)言編譯鏈接過(guò)程要把我們編寫(xiě)的一個(gè)C程序源代碼轉(zhuǎn)換成可以在硬件上運(yùn)行的程序(可執(zhí)行代碼),需要進(jìn)行編譯和鏈接。
    的頭像 發(fā)表于 08-21 10:06 ?3271次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言</b>的<b class='flag-5'>編譯</b>鏈接過(guò)程

    Rust語(yǔ)言錯(cuò)誤處理的機(jī)制

    在Rust語(yǔ)言中,錯(cuò)誤處理是一項(xiàng)非常重要的任務(wù)。由于Rust語(yǔ)言采用靜態(tài)類(lèi)型檢查,在編譯時(shí)就能發(fā)現(xiàn)很多潛在的錯(cuò)誤,這使得程序員能夠更加自信和
    的頭像 發(fā)表于 09-19 14:54 ?2129次閱讀

    C語(yǔ)言編譯過(guò)程是怎樣的

    C語(yǔ)言C語(yǔ)言編譯過(guò)程,各過(guò)程作用預(yù)處理階段源碼文件
    發(fā)表于 10-27 09:00

    如何將高級(jí)C語(yǔ)言編譯成機(jī)器碼

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

    C語(yǔ)言編譯過(guò)程中的錯(cuò)誤分析

      語(yǔ)言的最大特點(diǎn)是:功能強(qiáng)、使用方便靈活。C編譯的程序?qū)φZ(yǔ)法檢查并不象其它高級(jí)語(yǔ)言那么嚴(yán)格,這就給編程人員留下“靈活的余地”,但還是由于這個(gè)靈活給程序的調(diào)試
    發(fā)表于 09-11 11:43 ?1463次閱讀

    C語(yǔ)言編程時(shí)常犯的18種錯(cuò)誤

    C語(yǔ)言的最大特點(diǎn)是:功能強(qiáng)、使用方便靈活。C編譯的程序?qū)φZ(yǔ)法檢查并不象其它高級(jí)語(yǔ)言那么嚴(yán)格,這就給編程人員留下“靈活的余地”,但還是由于這個(gè)
    的頭像 發(fā)表于 02-27 14:51 ?6652次閱讀

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

    本文檔介紹了針對(duì)PIC18 MCU的MPLAB? C編譯器(以前的說(shuō)法,本文檔稱(chēng)為MPLAB C18)與MPLAB XC8 C編譯器間的差異
    發(fā)表于 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>器的詳細(xì)概述

    C語(yǔ)言編譯器中有哪些錯(cuò)誤信息詳細(xì)中英文對(duì)比

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

    C語(yǔ)言里extern "C" 是什么意思?

    通常用于C++和C混合編程的時(shí)候,為了防止C++的編譯在編譯C文件的時(shí)候出現(xiàn)
    的頭像 發(fā)表于 09-07 11:09 ?7353次閱讀

    解析C語(yǔ)言編譯過(guò)程中所做的工作

    過(guò)程是有幫助的。而且清楚的了解編譯鏈接過(guò)程還對(duì)我們在編程時(shí)定位錯(cuò)誤,以及編程時(shí)盡量調(diào)動(dòng)編譯器的檢測(cè)錯(cuò)誤會(huì)有很大的幫助的。
    的頭像 發(fā)表于 06-27 10:21 ?3764次閱讀
    解析<b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言</b><b class='flag-5'>編譯</b>過(guò)程中所做的工作

    VScode編譯器如何配置C/C++編譯環(huán)境

    昨天有伙伴私信我,為什么我用C語(yǔ)言寫(xiě)的hello world幾行代碼,在編譯器里面報(bào)錯(cuò)了呢?
    的頭像 發(fā)表于 03-16 08:38 ?7021次閱讀

    c語(yǔ)言代碼錯(cuò)誤怎么找

    ,它們通常是由于C語(yǔ)言編寫(xiě)規(guī)則被打破所引起的。實(shí)際上,C編譯器會(huì)提供非常詳細(xì)的錯(cuò)誤消息,告訴我們?cè)谀膫€(gè)地方發(fā)生了
    的頭像 發(fā)表于 11-24 10:05 ?5641次閱讀

    為什么C語(yǔ)言要進(jìn)行編譯

    為什么我們編寫(xiě)的C語(yǔ)言要進(jìn)行編譯?什么是編譯編譯時(shí)發(fā)生了什么? 機(jī)器無(wú)法理解我們編寫(xiě)的C
    的頭像 發(fā)表于 11-24 15:47 ?2108次閱讀
    為什么<b class='flag-5'>C</b><b class='flag-5'>語(yǔ)言</b>要進(jìn)行<b class='flag-5'>編譯</b>

    C語(yǔ)言關(guān)鍵字分別發(fā)生在哪個(gè)階段

    以下C語(yǔ)言關(guān)鍵字,分別發(fā)生在哪個(gè)階段? 第一個(gè),define。 首先得糾正一下,define 并不是C語(yǔ)言里面的關(guān)鍵字,即使加了井號(hào),也不是
    的頭像 發(fā)表于 11-24 10:31 ?790次閱讀