指針賦予了C編程最大的靈活性;結(jié)構(gòu)體使得C程序整齊而緊湊;聯(lián)合體在某些要求注重效率的場合有精彩的表現(xiàn),這三個(gè)要素是C語言的精華。
    然而,精華并不意味著完美,C語言在賦予程序員足夠靈活性的同時(shí),也給了程序員很多犯錯(cuò)誤的機(jī)會(huì)。所以有必要關(guān)注指針、結(jié)構(gòu)體和聯(lián)合體的實(shí)現(xiàn)細(xì)節(jié),從而">

欧美成人aaaaa免费视频_亚洲欧美激情小说另类_欧美激情一区二区三区视频_一级在线|欧洲

技術(shù)頻道

指針、結(jié)構(gòu)體、聯(lián)合體的安全規(guī)范

指針賦予了C編程最大的靈活性;結(jié)構(gòu)體使得C程序整齊而緊湊;聯(lián)合體在某些要求注重效率的場合有精彩的表現(xiàn),這三個(gè)要素是C語言的精華。
然而,精華并不意味著完美,C語言在賦予程序員足夠靈活性的同時(shí),也給了程序員很多犯錯(cuò)誤的機(jī)會(huì)。所以有必要關(guān)注指針、結(jié)構(gòu)體和聯(lián)合體的實(shí)現(xiàn)細(xì)節(jié),從而保障程序的安全性。
在此.第一部分介紹《MISRA—C:2004》中與指針相關(guān)的部分規(guī)則,第二部分講解結(jié)構(gòu)體和聯(lián)合體的操作規(guī)范。下文中凡是未加特殊說明的都是強(qiáng)制(required)規(guī)則,個(gè)別推薦(advisory)規(guī)則加了“推薦”標(biāo)示。
1 指針的安全規(guī)范
《MISRA—C:2004》關(guān)于指針的規(guī)范主要分為三個(gè)部分:指針的類型轉(zhuǎn)換規(guī)則、指針運(yùn)算的規(guī)則和指針的有效性規(guī)則。
1.1 指針的類型轉(zhuǎn)換
指針類型轉(zhuǎn)換是個(gè)高風(fēng)險(xiǎn)的操作,所以應(yīng)該盡量避免進(jìn)行這個(gè)操作。MISRA—C對(duì)其中可能造成嚴(yán)重錯(cuò)誤的情況作了嚴(yán)格的限定,選擇其中兩條作簡要分析。
規(guī)則11.4(推薦):指向不同數(shù)據(jù)類型的指針之間不能相互轉(zhuǎn)換。
思考如下程序:
uint8_t*pl;
uint32)_t*p2;
p2=(uint32_t*)pl;
/*注:uint8_t表示8位無符號(hào)整型,uint3_t表示32位無符號(hào)整型。*/
程序員希望將從p1單元開始的4個(gè)字節(jié)組成一個(gè)32付的整型來參與運(yùn)算。
如果CPU允許各種數(shù)據(jù)對(duì)象存放在任意的存儲(chǔ)單元,則以上轉(zhuǎn)換沒有問題。但某些CPU對(duì)某種(些)數(shù)據(jù)類型加強(qiáng)了對(duì)齊限制,要求這些數(shù)據(jù)對(duì)象占用一定的地址空間,比如某些字節(jié)尋址的CPU會(huì)要求32位(4字節(jié))整型存放在4的整倍數(shù)地址上。在這個(gè)前提下.思考程序中的指針轉(zhuǎn)換:假設(shè)pl一開始指向的是0x00O3單元(對(duì)uint8_t型的整型沒有對(duì)齊要求),則執(zhí)行最后一行強(qiáng)制轉(zhuǎn)換后,p2到底指向哪個(gè)單元就無法預(yù)料了。
規(guī)則1 1.5:指針轉(zhuǎn)換過程中不允許丟失指針的const、volatile屬性。按如下定義指針:
uIntl6一t x;
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;
則以下指針轉(zhuǎn)換是允許的:
pl=cpi;
以下指針轉(zhuǎn)換是不允許的:
pi=(umtl6_t*)pci;
pi=(uintl6_t*)pvil
ppi=(uintl6_t* *)pcpi;
ppi=(uintl6_I**)ppci+
以上非法指針類型轉(zhuǎn)換將會(huì)丟失const或者volatile類型。丟失const屬性,將有可能導(dǎo)致在對(duì)只讀內(nèi)容進(jìn)行寫操作時(shí),編譯器不會(huì)發(fā)出警告,編譯器將不對(duì)具有volatile屬性的變量作優(yōu)化;丟失volatile屬性,編譯器的優(yōu)化可能導(dǎo)致程序員預(yù)先設(shè)計(jì)的硬件時(shí)序操作失效,這樣的錯(cuò)誤很難發(fā)現(xiàn)。關(guān)于const和volatile關(guān)鍵字的詳細(xì)作用,讀者可參考ISOC獲取更多信息。
1.2 指針的運(yùn)算
ISOC標(biāo)準(zhǔn)中,對(duì)指向數(shù)組成員的指針運(yùn)算(包括算術(shù)運(yùn)算、比較等)做了規(guī)范定義,除此以外的指針運(yùn)算屬于未定義(undefined)范圍,具體實(shí)現(xiàn)有賴于具體編譯器,其安全性無法得到保障,MISRA—C中對(duì)指針運(yùn)算的合法范圍做了如下限定。
規(guī)則17.1:只有指向數(shù)組的指針才允許進(jìn)行算術(shù)運(yùn)算①。
規(guī)則17 2:只有指向同一個(gè)數(shù)組的兩個(gè)指針才允許相減 ②。
規(guī)則17 3:只有指向同一個(gè)數(shù)組的兩個(gè)指針才允許用>,>=,<,<=等關(guān)系運(yùn)算符進(jìn)行比較。
為了盡最大可能減少直接進(jìn)行指針運(yùn)算帶來的隱患,尤其是程序動(dòng)態(tài)運(yùn)行時(shí)可能發(fā)生的數(shù)組越界等問題,MISRA—C對(duì)指針運(yùn)算作了更為嚴(yán)格的規(guī)定。規(guī)則17 4:只允許用數(shù)組索引做指針運(yùn)算。按如下方式定義數(shù)組和指針:
uint8_t a[10];
uint8_t *p;
則*(p+5)=O是不允許的.而p[5]=O則是允許的,盡管就這段程序而言,二者等價(jià)。
以下給出一段程序,讀者可參照相應(yīng)程序行的注釋,細(xì)細(xì)品味上述規(guī)則的含義。
void my_fn(uInt*_t*p1.uint8_t p2[]){
①其實(shí)此處的算術(shù)運(yùn)算僅限定于指針加減某個(gè)整數(shù).比如ppoint=point一5.ppoint++等。0兩個(gè)指針可指向不同的散組成員。
uint8_t index=0;
uint8_t *p3
uint8_t *p4;
*pl=O;
p1++; /*不允許,pl不是指向數(shù)組的指針*/
p1=p1+5;/*不允許,pl不是指向數(shù)組的指針*/
pl[5]=O; /*不允許,p1不是指向數(shù)組的指針*/
p3=&p1[5];/*不允許,pl不是指向數(shù)組的指針*/
p2[0]=O;
index++;
index=index+5:
p2[index]=0; /*允許*/
*(p2+index)=O; /*不允許*/
p4=&p2[5]; /*允許*/
}
1.3 指針的有效性
下面介紹《MISRA—C:2004》中關(guān)于指針有效性的規(guī)則。
規(guī)則17 6:動(dòng)態(tài)分配對(duì)象的地址不允許在本對(duì)象消亡后傳給另外一個(gè)對(duì)象。
這條規(guī)則的實(shí)際意義是不允許將棧對(duì)象的地址傳給外部作用域的對(duì)象。
請(qǐng)看以下這段程序:
#include″stdi0.h″
char*getm(void){
char p[]=″hello world″;
return p;
intmain(){
char* str=NULL;
str=getm();
printf(str);
程序員希望最后的輸出結(jié)果是″hello world″這個(gè)字符串,然而實(shí)際運(yùn)行時(shí),卻出現(xiàn)亂碼(具體內(nèi)容依賴于編譯環(huán)境)。
簡單分析一下,由于chat p[]=″hell0 world″這條語句是在棧中分配空間存儲(chǔ)″hell0 world″這個(gè)字符串,當(dāng)函數(shù)getm()返回的時(shí)候,已分配的空間將會(huì)被釋放(但內(nèi)容并不會(huì)被銷毀),而priM(str)涉及系統(tǒng)調(diào)用,有數(shù)據(jù)壓棧,會(huì)修改從前分配給數(shù)組p[]存儲(chǔ)空間的內(nèi)容,導(dǎo)致程序無法得到預(yù)期的效果。
倘若將getm()函數(shù)體中的char p[]=″hell0 world″程序行改成char*q=″hello world″,則執(zhí)行main( )的時(shí)候可以正確輸出″hello world″,這是由于q指向的是靜態(tài)數(shù)據(jù)區(qū),而非棧中的某個(gè)單元。
所以,數(shù)組名是指針不假,但在實(shí)現(xiàn)細(xì)節(jié)上還是有很大的差異,程序員在使用指針的時(shí)候必須慎之又慎。
2 結(jié)構(gòu)體、聯(lián)合體的安全規(guī)范
規(guī)則18 4:不允許使用聯(lián)合體。這是一個(gè)不太近情理的規(guī)定,在具體闡述為何《MIS—RA—C:2004》如此“痛恨”聯(lián)合體之前,首先需要明確與聯(lián)合體相關(guān)的細(xì)節(jié):
①聯(lián)合體的末尾有多少個(gè)填充單元?
②聯(lián)合體中的各個(gè)成員如何對(duì)齊?
③多字節(jié)的數(shù)據(jù)類型高低字節(jié)如何排放順序?
④如果包含位字段(bit—field),各位如何排放順序?
針對(duì)細(xì)節(jié)3舉個(gè)例子。
程序段2.1
typedef union{
uilat32_t word;
uint8_t bytes[4];
}word_msg_t;
unit32_t read_nasg(void){
word_rnsg_t tmp;
/*注:tmn bvte[O]對(duì)府干tmp.word的高8位,tmp byter[l]對(duì)應(yīng)于
tmp.WOfO的次高8位,依次類推。*/
tmp.bytes[O]=read_byte();
tmp.bytes[1]=read_byte();
tmp.bytes[2]=read_byte();
tmp.bytes[3]=read_byte();
retlarn(trap.word);
}
以上代碼格式在各種通信協(xié)議中使用的頻率很高,接收端接收到的數(shù)據(jù)一般都以字節(jié)為單位存放,主控程序需要根據(jù)相應(yīng)的協(xié)議將接收到的多個(gè)字節(jié)進(jìn)行組合。為了實(shí)現(xiàn)相同的功能,《MISRA-C:2004》推薦了read_msg()函數(shù)的另外一種寫法。
程序段2.2
uint32_trcad_msg(void){
uint32_t word;
Word=((unit32_t)read_byte())<<24;
word=word│(((unit32_t)read_byte())<<16);
word=word│(((unit32_t)read_byted_byte<<8);
word=word│(((unit32_t)read_byte());
return(word):
}
無論從程序的清晰程度還是執(zhí)行效率來講,程序段2.1都優(yōu)于程序段2.2。然而,程序段2.1在Intel 80x86/Pentlurn體系(1ittle—endian,存儲(chǔ)多字節(jié)整數(shù)的時(shí)候低字節(jié)存放在低地址,高字節(jié)存放在高地址)CPU中和在Mo—torola 68K體系(big—endian,存儲(chǔ)多字節(jié)整數(shù)的時(shí)候高字節(jié)存放在低地址,低字節(jié)存放在高地址)cPu中的執(zhí)行結(jié)果完全不一樣。假設(shè)read_byte()函數(shù)返回的數(shù)據(jù)依次是0x01、0x02、0x03和0x04,則在Intel體系中,程序段2.1
中read_msg()函數(shù)的返回值是0x432l;在Motorola體系中,read_msg()的返回值是0x1234。
無論在Intel體系還是Motorola體系中,程序段2.2中read_msg()的返回值都是0x1 234。
以上是聯(lián)合體中多字節(jié)整型字節(jié)排放順序不定導(dǎo)致漏洞的一個(gè)例子。倘若不明確聯(lián)合體末尾填充的細(xì)節(jié),或者不清楚聯(lián)合體成員的對(duì)齊方式,或者不注意聯(lián)合體中位字段成員的位排列次序,都有可能導(dǎo)致錯(cuò)誤。作為將安全性放在第一位的C標(biāo)準(zhǔn),MlSRA—C禁止使用聯(lián)合體并非不可理喻。
然而,聯(lián)合體畢竟是C語言的一個(gè)重要元素,所以MISRA—C主張禁止使用聯(lián)合體的同時(shí),也為效率和資源要求比較苛刻的情況開了一扇門,程序員在明確聯(lián)合體各個(gè)實(shí)現(xiàn)細(xì)節(jié)的前提下,在萬不得已的時(shí)候,仍可謹(jǐn)慎使用聯(lián)合體,在不同體系的CPU間移植程序的時(shí)候要注意做相應(yīng)的修改。
此外,《MISRA—C:2004》中也對(duì)結(jié)構(gòu)體和聯(lián)合體的編程風(fēng)格作了限定。
規(guī)則18 1:所有結(jié)構(gòu)體和聯(lián)合體的定義必須保證完整性。
由于涉及ISOC中類型定義完整性等概念,礙于篇幅的原因,此處就不再贅述,讀者可以參閱《MISRA-C:2004》一書和ISOC標(biāo)準(zhǔn)以了解更多信息,完善自己的編程風(fēng)格。
3 小 結(jié)
總而言之,對(duì)于C程序中最為靈活的指針、結(jié)構(gòu)體和聯(lián)合體,程序員不僅僅要關(guān)注其定義和操作的一般方法,更要注重實(shí)現(xiàn)的細(xì)節(jié)。由于指針、聯(lián)合體等的功能性錯(cuò)誤一般都可以逃過編譯器的檢查,所以稍有疏忽,就可能導(dǎo)致程序在運(yùn)行的時(shí)候出現(xiàn)嚴(yán)重錯(cuò)誤,程序員必須以嚴(yán)謹(jǐn)甚至苛刻的態(tài)度對(duì)待指針、結(jié)構(gòu)體和聯(lián)合體。

文章版權(quán)歸西部工控xbgk所有,未經(jīng)許可不得轉(zhuǎn)載。

欧美成人aaaaa免费视频_亚洲欧美激情小说另类_欧美激情一区二区三区视频_一级在线|欧洲

      国产精品视频免费| 另类图片综合电影| 亚洲国产精品美女| 国产精品成人va在线观看| 欧美在线3区| 在线综合亚洲| 亚洲日本成人在线观看| 国产亚洲人成a一在线v站| 欧美人与禽猛交乱配视频| 欧美在线视频免费| 亚洲一区二区精品在线| 亚洲精品无人区| 在线观看视频亚洲| 国模精品一区二区三区| 国产欧美日本一区二区三区| 欧美日本高清| 女女同性精品视频| 狼人天天伊人久久| 久久理论片午夜琪琪电影网| 欧美一级午夜免费电影| 在线视频亚洲欧美| 夜夜嗨av一区二区三区四区 | 国产日本欧美一区二区三区| 欧美视频免费| 欧美日韩国产一区二区三区| 欧美日韩mv| 欧美日韩1区2区| 欧美激情综合网| 香蕉久久夜色精品国产使用方法| 91久久精品一区二区别| 亚洲电影有码| 亚洲国产一区二区三区青草影视| 亚洲国产精品成人| 亚洲国产欧美一区二区三区久久 | 欧美午夜精品久久久久久人妖 | 在线免费观看日本欧美| 在线观看欧美精品| 亚洲精品欧美日韩| 9久re热视频在线精品| 亚洲视频精选在线| 欧美一区二区三区四区视频| 欧美一级二级三级蜜桃| 久久午夜精品一区二区| 欧美高清不卡| 欧美精品在线免费| 国产精品日本精品| 国内精品写真在线观看| 91久久精品美女高潮| 一道本一区二区| 欧美中文在线免费| 欧美高清在线| 国产精品视频99| 怡红院精品视频在线观看极品| 亚洲电影免费观看高清| 亚洲午夜久久久| 久久久久久噜噜噜久久久精品| 欧美成人性生活| 国产精品一区二区久久久| 在线播放国产一区中文字幕剧情欧美| 亚洲精品国产精品乱码不99按摩| 亚洲无限av看| 母乳一区在线观看| 国产日韩精品在线播放| 亚洲精品乱码久久久久久蜜桃麻豆 | 久久精品国产v日韩v亚洲| 欧美不卡高清| 国产精品综合av一区二区国产馆| 在线观看欧美一区| 亚洲欧美一区二区激情| 欧美国产第一页| 红桃视频国产精品| 中文在线一区| 欧美激情中文字幕在线| 激情av一区| 午夜日韩视频| 欧美日韩在线一区二区三区| 黄色成人91| 欧美一区二区三区在线观看| 欧美日本韩国一区| 亚洲国产精品va在线看黑人| 欧美专区在线播放| 国产精品亚洲综合色区韩国| 日韩午夜在线电影| 欧美波霸影院| 亚洲国产你懂的| 麻豆91精品| 伊人婷婷欧美激情| 久久婷婷av| 激情成人综合| 久久久天天操| 激情久久婷婷| 久久久久久久尹人综合网亚洲 | 欧美一区二区三区在线| 国产精品亚洲激情| 亚洲一区二区三区四区在线观看| 欧美激情中文字幕乱码免费| 亚洲国产一区二区三区高清| 久久嫩草精品久久久精品| 国产专区精品视频| 久久免费午夜影院| 亚洲国产精品视频一区| 一本色道久久加勒比88综合| 欧美日韩美女一区二区| 亚洲午夜极品| 国产日本欧美视频| 久久精品国产视频| 国产一区二区无遮挡| 久久久青草婷婷精品综合日韩| 影音先锋日韩精品| 欧美高清视频一区二区三区在线观看 | 久久亚洲国产精品日日av夜夜| 韩国一区二区三区美女美女秀| 久久久久久久尹人综合网亚洲 | 久久成人免费网| 国产三级精品在线不卡| 久久人人看视频| 亚洲精品人人| 欧美亚男人的天堂| 久久国产精品久久久久久久久久| 亚洲电影av| 欧美网站在线| 久久精品中文字幕一区| 亚洲精品一区中文| 国产日韩精品一区二区浪潮av| 久久综合中文色婷婷| 一本久久青青| 国产三级欧美三级| 欧美另类视频在线| 欧美在线视频全部完| 亚洲欧洲精品一区| 国产精品一区二区女厕厕| 老司机成人在线视频| 一本色道久久综合精品竹菊| 国产日韩欧美在线| 欧美日韩蜜桃| 你懂的成人av| 欧美中文在线字幕| 一区二区免费在线播放| 国内精品久久久久久久影视麻豆 | 在线免费日韩片| 国产精品毛片va一区二区三区 | 国产乱人伦精品一区二区| 久久亚洲综合| 在线观看不卡av| 欧美激情中文字幕一区二区| 国产午夜一区二区三区| 欧美国产综合视频| 久久成人免费电影| 亚洲女性裸体视频| 日韩香蕉视频| 最新亚洲一区| 伊人成年综合电影网| 国产亚洲欧美中文| 国产久一道中文一区| 欧美日韩成人激情| 欧美大片在线观看一区二区| 久久人91精品久久久久久不卡| 亚洲男人av电影| 亚洲一区观看| 亚洲欧美在线高清| 午夜精品婷婷| 亚洲欧美日韩综合aⅴ视频| 夜夜精品视频一区二区| 亚洲免费观看| 夜夜爽99久久国产综合精品女不卡| 狠狠色狠狠色综合| 国产一区二区三区四区在线观看| 国产伦一区二区三区色一情| 国产九九视频一区二区三区| 国产精品国产馆在线真实露脸| 欧美日在线观看| 欧美系列电影免费观看| 国产精品久久久99| 国产精品男女猛烈高潮激情| 国产精品区一区| 国产亚洲激情在线| 亚洲大胆美女视频| 亚洲破处大片| 日韩亚洲欧美一区| 亚洲男女毛片无遮挡| 香蕉成人久久| 久久久久久久成人| 欧美大片免费观看| 欧美视频第二页| 国产亚洲精品aa午夜观看| 国产中文一区二区三区| 在线观看视频一区二区欧美日韩 | 欧美在线视频网站| 久久亚洲精品中文字幕冲田杏梨| 久久久亚洲综合| 欧美aaa级| 国产精品有限公司| 好看的亚洲午夜视频在线| 亚洲国产老妈| 亚洲一区在线播放| 久久野战av| 欧美午夜精品久久久久久超碰| 国产日韩一区二区三区| 亚洲国产精品激情在线观看| 宅男噜噜噜66一区二区66|