91精品一区二区三区久久久久久_欧美一级特黄大片色_欧美一区二区人人喊爽_精品一区二区三区av

位置:51電子網 » 技術資料 » 其它綜合

指針、結構體、聯合體的安全規范

發布時間:2007/8/30 0:00:00 訪問次數:948

來源:單片機及嵌入式系統應用  作者:清華大學 張樂平 邵貝貝


指針賦予了C編程最大的靈活性;結構體使得C程序整齊而緊湊;聯合體在某些要求注重效率的場合有精彩的表現,這三個要素是C語言的精華。


然而,精華并不意味著完美,C語言在賦予程序員足夠靈活性的同時,也給了程序員很多犯錯誤的機會。所以有必要關注指針、結構體和聯合體的實現細節,從而保障程序的安全性。


在此.第一部分介紹《MISRA—C:2004》中與指針相關的部分規則,第二部分講解結構體和聯合體的操作規范。下文中凡是未加特殊說明的都是強制(required)規則,個別推薦(advisory)規則加了“推薦”標示。


1  指針的安全規范


《MISRA—C:2004》關于指針的規范主要分為三個部分:指針的類型轉換規則、指針運算的規則和指針的有效性規則。


1.1  指針的類型轉換


指針類型轉換是個高風險的操作,所以應該盡量避免進行這個操作。MISRA—C對其中可能造成嚴重錯誤的情況作了嚴格的限定,選擇其中兩條作簡要分析。


規則11.4(推薦):指向不同數據類型的指針之間不能相互轉換。


思考如下程序:


uint8_t*pl;


uint32)_t*p2;


p2=(uint32_t*)pl;


/*注:uint8_t表示8位無符號整型,uint3_t表示32位無符號整型。*/


程序員希望將從p1單元開始的4個字節組成一個32付的整型來參與運算。


如果CPU允許各種數據對象存放在任意的存儲單元,則以上轉換沒有問題。但某些CPU對某種(些)數據類型加強了對齊限制,要求這些數據對象占用一定的地址空間,比如某些字節尋址的CPU會要求32位(4字節)整型存放在4的整倍數地址上。在這個前提下.思考程序中的指針轉換:假設pl一開始指向的是0x00O3單元(對uint8_t型的整型沒有對齊要求),則執行最后一行強制轉換后,p2到底指向哪個單元就無法預料了。


規則1 1.5:指針轉換過程中不允許丟失指針的const、volatile屬性。按如下定義指針:


uIntl6一tx;


uint16_t*const  cpi=&x;  /*const指針*/


uintl6_t*const  *pcpi;/*指向const指針的指針*/


const uintl6_t*  *ppci;/*指向const整型指針的指針*/


uIntl6_t**ppi ;


const  uint16_t   *pci;/*指向const整型的指針*/


volatik uint16_t*pvi;/*指向volatile整型的指針*/


uintl6_t*pi;


則以下指針轉換是允許的:


pl=cpi;


以下指針轉換是不允許的:


pi=(umtl6_t*)pci;


pi=(uintl6_t*)pvil


ppi=(uintl6_t* *)pcpi;


ppi=(uintl6_I**)ppci+


以上非法指針類型轉換將會丟失const或者volatile類型。丟失const屬性,將有可能導致在對只讀內容進行寫操作時,編譯器不會發出警告,編譯器將不對具有volatile屬性的變量作優化;丟失volatile屬性,編譯器的優化可能導致程序員預先設計的硬件時序操作失效,這樣的錯誤很難發現。關于const和volatile關鍵字的詳細作用,讀者可參考ISOC獲取更多信息。


1.2  指針的運算


ISOC標準中,對指向數組成員的指針運算(包括算術運算、比較等)做了規范定義,除此以外的指針運算屬于未定義(undefined)范圍,具體實現有賴于具體編譯器,其安全性無法得到保障,MISRA—C中對指針運算的合法范圍做了如下限定。


規則17.1:只有指向數組的指針才允許進行算術運算①。


規則17 2:只有指向同一個數組的兩個指針才允許相減 ②。


規則17 3:只有指向同一個數組的兩個指針才允許用>,>=,<,<=等關系運算符進行比較。


為了盡最大可能減少直接進行指針運算帶來的隱患,尤其是程序動態運行時可能發生的數組越界等問題,MISRA—C對指針運算作了更為嚴格的規定。規則17 4:只允許用數組索引做指針運算。按如下方式定義數組和指針:


uint8_ta[10];


uint8_t*p;


則*(p+5)=O是不允許的.而p[5]=O則是允許的,盡管就這段程序而言,二者等價。


以下給出一段程序,讀者可參照相應程序行的注釋,細細品味上述規則的含義。


void my_fn(uInt*_t*p1.uint8_t p2[]){


①其實此處的算術運算僅限定于指針加減某個整數.比如ppoint=point一5.ppoint++等。0兩個指針可指向不同的散組成員。


uint8_t index=0;


uint8_t*p3


uint8_t*p4;


*pl=O;


p1++;/*不允許,pl不是指向數組的指針*/


p1=p1+5;/*不允許,pl不是指向數組的指針*/


pl[5]=O;&

來源:單片機及嵌入式系統應用  作者:清華大學 張樂平 邵貝貝


指針賦予了C編程最大的靈活性;結構體使得C程序整齊而緊湊;聯合體在某些要求注重效率的場合有精彩的表現,這三個要素是C語言的精華。


然而,精華并不意味著完美,C語言在賦予程序員足夠靈活性的同時,也給了程序員很多犯錯誤的機會。所以有必要關注指針、結構體和聯合體的實現細節,從而保障程序的安全性。


在此.第一部分介紹《MISRA—C:2004》中與指針相關的部分規則,第二部分講解結構體和聯合體的操作規范。下文中凡是未加特殊說明的都是強制(required)規則,個別推薦(advisory)規則加了“推薦”標示。


1  指針的安全規范


《MISRA—C:2004》關于指針的規范主要分為三個部分:指針的類型轉換規則、指針運算的規則和指針的有效性規則。


1.1  指針的類型轉換


指針類型轉換是個高風險的操作,所以應該盡量避免進行這個操作。MISRA—C對其中可能造成嚴重錯誤的情況作了嚴格的限定,選擇其中兩條作簡要分析。


規則11.4(推薦):指向不同數據類型的指針之間不能相互轉換。


思考如下程序:


uint8_t*pl;


uint32)_t*p2;


p2=(uint32_t*)pl;


/*注:uint8_t表示8位無符號整型,uint3_t表示32位無符號整型。*/


程序員希望將從p1單元開始的4個字節組成一個32付的整型來參與運算。


如果CPU允許各種數據對象存放在任意的存儲單元,則以上轉換沒有問題。但某些CPU對某種(些)數據類型加強了對齊限制,要求這些數據對象占用一定的地址空間,比如某些字節尋址的CPU會要求32位(4字節)整型存放在4的整倍數地址上。在這個前提下.思考程序中的指針轉換:假設pl一開始指向的是0x00O3單元(對uint8_t型的整型沒有對齊要求),則執行最后一行強制轉換后,p2到底指向哪個單元就無法預料了。


規則1 1.5:指針轉換過程中不允許丟失指針的const、volatile屬性。按如下定義指針:


uIntl6一tx;


uint16_t*const  cpi=&x;  /*const指針*/


uintl6_t*const  *pcpi;/*指向const指針的指針*/


const uintl6_t*  *ppci;/*指向const整型指針的指針*/


uIntl6_t**ppi ;


const  uint16_t   *pci;/*指向const整型的指針*/


volatik uint16_t*pvi;/*指向volatile整型的指針*/


uintl6_t*pi;


則以下指針轉換是允許的:


pl=cpi;


以下指針轉換是不允許的:


pi=(umtl6_t*)pci;


pi=(uintl6_t*)pvil


ppi=(uintl6_t* *)pcpi;


ppi=(uintl6_I**)ppci+


以上非法指針類型轉換將會丟失const或者volatile類型。丟失const屬性,將有可能導致在對只讀內容進行寫操作時,編譯器不會發出警告,編譯器將不對具有volatile屬性的變量作優化;丟失volatile屬性,編譯器的優化可能導致程序員預先設計的硬件時序操作失效,這樣的錯誤很難發現。關于const和volatile關鍵字的詳細作用,讀者可參考ISOC獲取更多信息。


1.2  指針的運算


ISOC標準中,對指向數組成員的指針運算(包括算術運算、比較等)做了規范定義,除此以外的指針運算屬于未定義(undefined)范圍,具體實現有賴于具體編譯器,其安全性無法得到保障,MISRA—C中對指針運算的合法范圍做了如下限定。


規則17.1:只有指向數組的指針才允許進行算術運算①。


規則17 2:只有指向同一個數組的兩個指針才允許相減 ②。


規則17 3:只有指向同一個數組的兩個指針才允許用>,>=,<,<=等關系運算符進行比較。


為了盡最大可能減少直接進行指針運算帶來的隱患,尤其是程序動態運行時可能發生的數組越界等問題,MISRA—C對指針運算作了更為嚴格的規定。規則17 4:只允許用數組索引做指針運算。按如下方式定義數組和指針:


uint8_ta[10];


uint8_t*p;


則*(p+5)=O是不允許的.而p[5]=O則是允許的,盡管就這段程序而言,二者等價。


以下給出一段程序,讀者可參照相應程序行的注釋,細細品味上述規則的含義。


void my_fn(uInt*_t*p1.uint8_t p2[]){


①其實此處的算術運算僅限定于指針加減某個整數.比如ppoint=point一5.ppoint++等。0兩個指針可指向不同的散組成員。


uint8_t index=0;


uint8_t*p3


uint8_t*p4;


*pl=O;


p1++;/*不允許,pl不是指向數組的指針*/


p1=p1+5;/*不允許,pl不是指向數組的指針*/


pl[5]=O;&

相關IC型號

熱門點擊

 

推薦技術資料

羅盤誤差及補償
    造成羅盤誤差的主要因素有傳感器誤差、其他磁材料干擾等。... [詳細]
版權所有:51dzw.COM
深圳服務熱線:13751165337  13692101218
粵ICP備09112631號-6(miitbeian.gov.cn)
公網安備44030402000607
深圳市碧威特網絡技術有限公司
付款方式


 復制成功!
芮城县| 教育| 丹东市| 铜陵市| 潞城市| 曲靖市| 清流县| 改则县| 永安市| 烟台市| 德庆县| 天峻县| 宣化县| 丰城市| 新野县| 易门县| 水富县| 大英县| 丘北县| 浦北县| 简阳市| 芜湖市| 新沂市| 高碑店市| 甘谷县| 仁寿县| 苏尼特左旗| 湾仔区| 邛崃市| 万全县| 景德镇市| 哈巴河县| 万荣县| 繁昌县| 资兴市| 堆龙德庆县| 洞口县| 洛南县| 天峻县| 会宁县| 上虞市|