免费高清特黄a大片,九一h片在线免费看,a免费国产一级特黄aa大,国产精品国产主播在线观看,成人精品一区久久久久,一级特黄aa大片,俄罗斯无遮挡一级毛片

分享

“安全第一”的C語言編程規(guī)范

 Jugg_Bug 2013-08-28
C語言是開發(fā)嵌入式應用的主要工具,然而C語言并非是專門為嵌入式系統(tǒng)設計,相當多的嵌入式系統(tǒng)較一般計算機系統(tǒng)對軟件安全性有更苛刻的要求。1998年,MISRA指出,一些在C看來可以接受,卻存在安全隱患的地方有127處之多。2004年,MISRA對C的限制增加到141條。

  嵌入式系統(tǒng)應用工程師借用計算機專家創(chuàng)建的C語言,使嵌入式系統(tǒng)應用得以飛速發(fā)展,而MISRAC是嵌入式系統(tǒng)應用工程師對C語言嵌入式應用做出的貢獻。如今MISRA C已經(jīng)被越來越多的企業(yè)接受,成為用于嵌入式系統(tǒng)的C語言標準,特別是對安全性要求極高的嵌入式系統(tǒng),軟件應符合MISRA標準。

  從本期開始,本刊將分6期,與讀者共同學習MISRAC。
  第一講:“‘安全第一’的C語言編程規(guī)范”,簡述MISRAC的概況。
  第二講:“跨越數(shù)據(jù)類型的重重陷阱”,介紹規(guī)范的數(shù)據(jù)定義和操作方式,重點在隱式數(shù)據(jù)類型轉(zhuǎn)換中的問題。
  第三講:“指針、結(jié)構(gòu)體、聯(lián)合體的安全規(guī)范”,解析如何安全而高效地應用指針、結(jié)構(gòu)體和聯(lián)合體。
  第四講:“防范表達式的失控”,剖析MISRAC中關(guān)于表達式、函數(shù)聲明和定義等的不良使用習慣,最大限度地減小各類潛在錯誤。
  第五講:“準確的程序流控制”,表述C語言中控制表達式和程序流控制的規(guī)范做法。
  第六講:“構(gòu)建安全的編譯環(huán)境”,講解與編譯器相關(guān)的規(guī)范編寫方式,避免來自編譯器的隱患。

   C/C++語言無疑是當今嵌入式開發(fā)中最為常見的語言。早期的嵌入式程序大都是用匯編語言開發(fā)的,但人們很快就意識到匯編語言所帶來的問題——難移植、難復用、難維護和可讀性極差。很多程序會因為當初開發(fā)人員的離開而必須重新編寫,許多程序員甚至連他們自己幾個月前寫成的代碼都看不懂。C/C++語言恰恰可以解決這些問題。作為一種相對“低級”的高級語言,C/C++語言能夠讓嵌入式程序員更自由地控制底層硬件,同時享受高級語言帶來的便利。對于C語言和C++語言,很多的程序員會選擇C語言,而避開龐大復雜的C++語言。這是很容易理解的——C語言寫成的代碼量比C++語言的更小些,執(zhí)行效率也更高。

  對于程序員來說,能工作的代碼并不等于“好”的代碼?!昂谩贝a的指標很多,包括易讀、易維護、易移植和可靠等。其中,可靠性對嵌入式系統(tǒng)非常重要,尤其是在那些對安全性要求很高的系統(tǒng)中,如飛行器、汽車和工業(yè)控制中。這些系統(tǒng)的特點是:只要工作稍有偏差,就有可能造成重大損失或者人員傷亡。一個不容易出錯的系統(tǒng),除了要有很好的硬件設計(如電磁兼容性),還要有很健壯或者說“安全”的程序。

  然而,很少有程序員知道什么樣的程序是安全的程序。很多程序只是表面上可以干活,還存在著大量的隱患。當然,這其中也有C語言自身的原因。因為C語言是一門難以掌握的語言,其靈活的編程方式和語法規(guī)則對于一個新手來說很可能會成為機關(guān)重重的陷阱。同時,C語言的定義還并不完全,即使是國際通用的C語言標準,也還存在著很多未完全定義的地方。要求所有的嵌入式程序員都成為C語言專家,避開所有可能帶來危險的編程方式,是不現(xiàn)實的。最好的方法是有一個針對安全性的C語言編程規(guī)范,告訴程序員該如何做。
1 MISRAC規(guī)范  1994年,在英國成立了一個叫做汽車工業(yè)軟件可靠性聯(lián)合會(The Motor Industry Software Reliability Association,以下簡稱MISRA)的組織。它是致力于協(xié)助汽車廠商開發(fā)安全可靠的軟件的跨國協(xié)會,其成員包括:AB汽車電子、羅孚汽車、賓利汽車、福特汽車、捷豹汽車、路虎公司、Lotus公司、MIRA公司、Ricardo公司、TRW汽車電子、利茲大學和福特VISTEON汽車系統(tǒng)公司。

  經(jīng)過了四年的研究和準備,MISRA于1998年發(fā)布了一個針對汽車工業(yè)軟件安全性的C語言編程規(guī)范——《汽車專用軟件的C語言編程指南》(Guidelines for the Use of the C Language in Vehicle Based Software),共有127條規(guī)則,稱為MISRAC:1998。[Page]

  C語言并不乏國際標準。國際標準化組織(International Organization of Standardization,簡稱ISO)的“標準C語言”經(jīng)歷了從C90、C96到C99的變動。但是,嵌入式程序員很難將ISO標準當作編寫安全代碼的規(guī)范。一是因為標準C語言并不是針對代碼安全的,也并不是專門為嵌入式應用設計的;二是因為“標準C語言”太龐大了,很難操作。MISRAC:1998規(guī)范的產(chǎn)生恰恰彌補了這方面的空白。

  隨著很多汽車廠商開始接受MISRAC編程規(guī)范,MISRAC:1998也成為汽車工業(yè)中最為著名的有關(guān)安全性的C語言規(guī)范。2004年,MISRA出版了該規(guī)范的新版本——MISRAC:2004。在新版本中,還將面向的對象由汽車工業(yè)擴大到所有的高安全性要求(Critical)系統(tǒng)。在MISRAC:2004中,共有強制規(guī)則121條,推薦規(guī)則20條,并刪除了15條舊規(guī)則。任何符合MISRAC:2004編程規(guī)范的代碼都應該嚴格的遵循121條強制規(guī)則的要求,并應該在條件允許的情況下盡可能符合20條推薦規(guī)則。

  MISRAC:2004將其141條規(guī)則分為21個類別,每一條規(guī)則對應一條編程準則。詳細情況如表1所列。


      

  最初,MISRAC:1998編程規(guī)范的建立是為了增強汽車工業(yè)軟件的安全性??赡茉斐善囀鹿实脑蛴泻芏?,如圖1所示,設計和制造時埋下的隱患約占總數(shù)的15%,其中也包括軟件的設計和制造。MISRAC:1998就是為了減小這部分隱患而制定的。

  MISRAC編程規(guī)范的推出迎合了很多汽車廠商的需要,因為一旦廠商在程序設計上出現(xiàn)了問題,用來補救的費用將相當可觀。1999年7月22日,通用汽車公司(General Motors)就曾經(jīng)因為其軟件設計上的一個問題,被迫召回350萬輛已經(jīng)出廠的汽車,損失之大可想而知。

  MISRAC規(guī)范不僅在汽車工業(yè)開始普及,也同時影響到了嵌入式開發(fā)的其他方向。嵌入式實時操作系統(tǒng)μC/OSII的2.52版本雖然已經(jīng)于2000年通過了美國航空管理局(FAA)的安全認證,但2003年作者就根據(jù)MISRAC:1998規(guī)范又對源碼做了相應的修改,如將

  if ((pevent->OSEventTbl[y] &= ~bitx) == 0) {
    /*… */
  }

的寫法,改寫成

  pevent->OSEventTbl[y] &= ~bitx;
  if (pevent->OSEventTbl[y] == 0) {
  /*… */
  }

發(fā)布了2.62的新版本,并宣稱其源代碼99%符合MISRAC:1998規(guī)范。

  一個程序能夠符合MISRAC編程規(guī)范,不僅需要程序員按照規(guī)范編程,編譯器也需要對所編譯的代碼進行規(guī)則檢查。現(xiàn)在,很多編譯器開發(fā)商都對MISRAC規(guī)范有了支持,比如IAR的編譯器就提供了對MISRAC:1998規(guī)范127條規(guī)則的檢查功能。
2 MISRAC對安全性的理解
  MISRAC:2004的專家們大都來自于軟件工業(yè)或者汽車工業(yè)的知名公司,規(guī)范的制定不僅僅像過去一樣局限于汽車工業(yè)的C語言編程,同時還涵蓋了其他高安全性系統(tǒng)。



  MISRAC:2004認為C程序設計中存在的風險可能由5個方面造成:程序員的失誤、程序員對語言的誤解、程序員對編譯器的誤解、編譯器的錯誤和運行出錯(runtime errors)。

  程序員的失誤是司空見慣的。程序員是人,難免會犯錯誤。很多由程序員犯下的錯誤可以被編譯器及時地糾正(如鍵入錯誤的變量名等),但也有很多會逃過編譯器的檢查。相信任何一個程序員都曾經(jīng)犯過將“= =”誤寫成“=”的錯誤,編譯器可能不會認為

   if(x=y)

是一個程序員的失誤。

  再舉個例子,大家都知道++運算符。假如有下面的指令:

  i=3;
  printf(“%d”,++i);

輸出應該是多少?如果是:

  printf(“%d”,i++);

呢?如果改成-i++呢?i+++i呢?i+++++i呢?絕大多數(shù)程序員恐怕已經(jīng)糊涂了。在MISRAC:2004中,會明確指出++或--運算符不得和其他運算符混合使用。

  C語言非常靈活,它給了程序員非常大的自由。但事情有好有壞,自由越大,犯錯誤的機會也就越多。[Page]

  如果說有些錯誤是程序員無心之失的話,那么因為程序員對C語言本身或是編譯器特性的誤解而造成的錯誤就是“明”知故犯了。C語言有一些概念很難掌握,非常容易造成誤解,如表達式的計算。請看下面這條語句:

   if ( ishigh && (x == i++))

很多程序員認為執(zhí)行了這條指令后,i變量的值就會自動加1。但真正的情況如何呢?MISRA中有一條規(guī)則:邏輯運算符&&或||的右操作數(shù)不得帶有副作用(side effect)*,就是為了避免這種情況下可能出現(xiàn)的問題。

*所謂帶有副作用,就是指執(zhí)行某條語句時會改變運行環(huán)境,如執(zhí)行x=i++之后,i的值會發(fā)生變化。

  另外,不同編譯器對同一語句的處理可能是不一樣的。例如整型變量的長度,不同編譯器的規(guī)定就不同。這就要求程序員不僅要清楚C語言本身的特性,還要了解所用的編譯器,難度很大。

  還有些錯誤是由編譯器(或者說是編寫編譯器的程序員)本身造成的。這些錯誤往往較難發(fā)現(xiàn),有可能會一直存留在最后的程序中。

  運行錯誤指的是那些在運行時出現(xiàn)的錯誤,如除數(shù)等于零、指針地址無效等問題。運行錯誤在語法檢查時一般無法發(fā)現(xiàn),但一旦發(fā)生很可能導致系統(tǒng)崩潰。例如:

#define NULL 0
   ……
  char* p;
  p=NULL;
  printf(“Location of 0 is %d\n”, *p);

語法上沒有任何問題,但在某些系統(tǒng)上卻可能運行出錯。

  C語言可以產(chǎn)生非常緊湊、高效的代碼,一個原因就是C語言提供的運行錯誤檢查功能很少,雖然運行效率得以提高,但也降低了系統(tǒng)的安全性。

  有句話說得好,“正確的觀念重于一切”。MISRAC規(guī)范對于嵌入式程序員來講,一個很重要的意義就是提供給他們一些建議,讓他們逐漸樹立一些好的編程習慣和編程思路,慢慢摒棄那些可能存在風險的編程行為,編寫出更為安全、健壯的代碼。比如,很多嵌入式程序員都會忽略注釋的重要性,但這樣的做**降低程序的可讀性,也會給將來的維護和移植帶來風險。嵌入式程序員經(jīng)常要接觸到各種的編譯器,而很多C程序在不同編譯器下的處理是不一樣的。MISRAC:2004有一條強制規(guī)則,要求程序員把所有和編譯器特性相關(guān)的C語言行為記錄下來。這樣在程序員做移植工作時,風險就降低了。
3 MISRAC的負面效應  程序員可能會擔心采用MISRAC:2004規(guī)范會對他們的程序有負面影響,比如可能會影響代碼量、執(zhí)行效率和程序可讀性等。應該說,這種擔心不無道理??v觀141條MISRAC:2004編程規(guī)范,大多數(shù)的規(guī)則并不會對程序的代碼量、執(zhí)行效率和可讀性造成什么大的影響;一部分規(guī)則可能會以增加存儲器的占用空間為代價來增加執(zhí)行效率,或者增加代碼的可讀性;但是,也確實存在著一些規(guī)則可能會降低程序的執(zhí)行效率。

  一個典型的例子就是關(guān)于聯(lián)合體的使用。MISRAC:2004有一條規(guī)則明確指出:不得使用聯(lián)合體。這是因為,在聯(lián)合體的存儲方式(如位填充、對齊方式、位順序等)上,各種編譯器的處理可能不同。比如,經(jīng)常會有程序員這樣做:一邊將采集得到的數(shù)據(jù)按照某種類型存入一個聯(lián)合體,而同時又采用另外一種數(shù)據(jù)類型將該數(shù)據(jù)讀出。如下面這段程序:

  typedef union{
    uint32_t word;
    uint8_t bytes[4];
  }word_msg_t;
  unit32_t read_word_big_endian (void) {
    word_msg_t tmp;
    tmp.bytes[0] = read_byte();
    tmp.bytes[1] = read_byte();
    tmp.bytes[2] = read_byte();
    tmp.bytes[3] = read_byte();
    return (tmp.word);
  }

  原理上,這種聯(lián)合體很像是一個硬件上的雙口RAM存儲器。但程序員必須清楚,這種做法是有風險的。MISRAC:2004推薦用下面這種方法來做:

   uint32_t read_word_big_endian (void) {
    uint32_t word;
    word=((unit32_t)read_byte())<<24;[Page]
    word=word|(((unit32_t)read_byte())<<16);
    word=word|(((unit32_t)read_byte())<<8);
    word=word| ((unit32_t)read_byte());
    return(word);
  }

  先不論為什么這樣做會更安全,只談執(zhí)行效率,這種采用二進制數(shù)移位的方法遠遠不如使用聯(lián)合體。到底是使用更安全的做法,還是采用效率更高的做法,需要程序員權(quán)衡。對于一些要求執(zhí)行效率很高的系統(tǒng),使用聯(lián)合體仍然是可以接受的方法。當然,這是建立在程序員充分了解所用編譯器的基礎上的,而且程序員必須對這種做法配有相應的注釋。
4 發(fā)展中的MISRAC  MISRAC并非完美,它自身的發(fā)展也印證了這一點。MISRAC:2004就去掉了MISRAC:1998中的15條規(guī)則。今后的發(fā)展,MISRAC仍然要解決很多問題。比如,MISRAC:2004是基于C90標準的,但最新的國際C標準是C99,而C99中沒有確切定義的C語言特性幾乎比C90多了一倍,MISRAC如何適應新的標準還需要進一步探討。

  另外,C++在嵌入式應用中也越來越受到重視,MISRA正在著手制定MISRAC++編程規(guī)范。讀者可以通過訪問網(wǎng)站http://www.了解MISRAC的發(fā)展動向。
5 對MISRAC的思考  嵌入式系統(tǒng)并不算是一個獨立的學科,但作為一個發(fā)展中的行業(yè),它確實需要有一些自己的創(chuàng)新之處。嵌入式工程師們不應僅僅局限于從計算機專家那里學習相關(guān)理論知識,并運用于自己的項目,還應該共同努力去完善自己行業(yè)的標準和規(guī)范,為嵌入式系統(tǒng)的發(fā)展做出貢獻。MISRAC編程規(guī)范就是一個很好的典范。它始于汽車工程師和軟件工程師經(jīng)驗的總結(jié),然后逐漸發(fā)展成為一種對整個嵌入式行業(yè)都有指導意義的規(guī)范。對于推動整個嵌入式行業(yè)的正規(guī)化發(fā)展,MISRAC無疑有著重要意義。

  從另一個角度講,MISRAC規(guī)范也可以看成是嵌入式工程師對軟件業(yè)的一種完善。嵌入式工程師雖然不是計算機專家,但卻對嵌入式應用有著最深刻的了解,將自己在嵌入式應用中的經(jīng)驗和體會貢獻給其他行業(yè),也是他們應該肩負的責任。

參考文獻
1 MISRAC:2004, Guidelines for the use of the C language in critical systems. The Motor Industry Software Reliability Association, 2004
2 Harbison III. Samuel P, Steele Jr. Guy L. C語言參考手冊. 邱仲潘,等譯. 第5版. 北京:機械工業(yè)出版社,2003
3 Kernighan. Brian W, Ritchie. Dennis M. C程序設計語言. 徐寶文,等譯. 第2版. 北京:機械工業(yè)出版社,2001
4 Koenig Andrew. C陷阱與缺陷. 高巍譯. 北京:人民郵電出版社,2002
5 McCall Gavin. Introduction to MISRAC:2004, Visteon UK, http://www.MISRAC2.com/
6 Hennell Mike. MISRA CIts role in the bigger picture of critical software development, LDRA. http://www.MISRAC2.com/
7 Hatton Les. The MISRA C Compliance Suite—The next step, Oakwood Computing. http://www.MISRAC2.com/
8 Montgomery Steve. The role of MISRA C in developing automotive software, Ricardo Tarragon. http://www.MISRAC2.com/

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多