編程規(guī)范哪家強 我把Misra C講一講
俗語講,無規(guī)矩不成方圓,有敬畏才知行止。
煌煌人世間,這邊是周吳鄭王,那邊廂何呂施張,大家遵守同一個規(guī)矩才能你來我往。
國有國法,行有行規(guī),每一行都要定出個規(guī)范和章程,才不至于天下熙熙,母鴨對公雞,天下攘攘,你推我也搡。
貓有貓的道,夜里不睡覺,狗有狗的道,見樹就撒尿。電子工程師寫代碼,耶耶切克鬧,編程規(guī)范就有好幾套。
比如被美國佬視為眼中釘、怎么打也打不死的華為,有一套自己的C語言編程規(guī)范,開篇便是大家風(fēng)范:清晰第一,簡潔為美,頗有幾分道可道、非常道的玄妙。
再比如被美國佬看做肉中刺,嚷嚷著連著Jack Ma一塊兒起訴的阿里,也有自己的一套編碼規(guī)范,雖然不局限于C語言,也妥妥的“風(fēng)清揚”氣場,起范兒。
這兩家都是中國IT行業(yè)的翹楚,搞一套自家的編程規(guī)范,有點振臂高呼,號召大家卷上一卷的意思。
不過,沒有金剛鉆,就不攬那瓷器活。小公司固然沒能力,卻也沒意愿搞一套自家的編程規(guī)范,因為Misra C自有現(xiàn)成,做個善假于物也的君子,不亦樂乎?
1、Misra C是啥
“Misra C”是The Motor Industry Software Reliability Association C Coding Standard(汽車工業(yè)軟件可靠性聯(lián)合會制定的C編碼標(biāo)準(zhǔn))的首字母縮寫,最早的版本問世于1998,是專門針對汽車工業(yè)軟件安全性的一種C語言編碼規(guī)范。
想要進(jìn)宮,必先自宮,馬要拉車,得先閹割。也可以認(rèn)為,為了提高程序的可靠性和健壯性,Misra C這把手術(shù)刀對天馬行空的C語言特性進(jìn)行了無情的閹割。
說到這里,為了避免老表們產(chǎn)生不必要的誤解,不得不提上兩句。
華為和阿里編程規(guī)范的側(cè)重點實則與Misra C有所不同,它們的關(guān)注點并不在程序的健壯性這種“里子”,而在于統(tǒng)一代碼風(fēng)格這個“面子”。為的是將程序員代碼私產(chǎn)轉(zhuǎn)化為公產(chǎn),以代碼的可讀性提高人員更迭對應(yīng)的可維護(hù)性和可重用性。
里子很重要,面子當(dāng)然也很重要。因為,代碼是軟件的最終體現(xiàn)形式,是將人的設(shè)計思維轉(zhuǎn)換為機器語言的橋梁。它不僅要實現(xiàn)功能,被機器所讀懂,更重要的是,依照熟悉的代碼風(fēng)格和良好的可讀性,它可以清晰地向閱讀它的碼農(nóng)們表達(dá)設(shè)計思想。
就跟現(xiàn)在上海的同胞既要捅嗓子又要捅鼻子一樣,代碼也得兩頭通!
這些代碼風(fēng)格如何,給大家?guī)讉€例子,自行體會一下吧。
比如說華為規(guī)定每行代碼不能超過120個字,阿里規(guī)定每行代碼不能超過80個字,再比如每個函數(shù)不能超過80行。。。
這些根據(jù)顯示器上能夠容納的字符數(shù)和行數(shù)而針對代碼風(fēng)格進(jìn)行的規(guī)范,正是Misra C所不曾涉及的。
Misra C不重形式,更重實質(zhì),它所關(guān)注的是代碼的安全性、穩(wěn)定性、魯棒性。比如說所有switch語句里都要有break,以防止意外發(fā)生時找不到處理分支。
再比如說,雖然使用遞歸能夠非常‘優(yōu)雅’地實現(xiàn)某個功能,但是Misra C規(guī)定:一個函數(shù)不能直接或者間接地調(diào)用自己!
Anyway,華為阿里編程規(guī)范和Misra C的終極目的都是為了讓程序員寫出一手好代碼,方向是一致的,道路是不同的。也可以說:
皓月當(dāng)空,以手指月,華為和阿里在乎的是那只手,而Misra C在乎的是那輪月。
2、Misra C的背景
黑格爾說:凡是存在的,都是合理的。那么,誕生于上個世紀(jì)70年代初的C語言,怎么就在上個世紀(jì)末的時候,迎來了Misra C這么個婆婆?
或者說,Misra C的合理性在哪兒?這個婆婆,看不上C大姐哪一點了?
C語言身材苗條(結(jié)構(gòu)緊湊)、能說會道(表達(dá)能力強)、溫順體貼(靈活性強),在嵌入式碼農(nóng)這個圈圈里,很是招人喜歡。
碼農(nóng)們喜歡換著花樣擺弄C語言,有時還會故意使用一些花里胡哨的特性。但是,正如張無忌他媽說過‘越是漂亮的女人越會騙人’一樣,越是靈活的特性,越會導(dǎo)致粗心大意的編碼人員寫出危險的代碼。
梅西說:“我不是天生強大,我只是天生要強”。灑家說:“C語言并非天生安全,它只是天生就帶著缺陷”。
所以,為了對治C語言先天的固有缺陷,Misra C橫空出世,針砭C弊。
金庸老爺子說:萬物相生相克,凡是毒物,七步之內(nèi)必有解****。C語言先天帶毒,自然有Misra C來跟它相愛相殺一番。
最初,Misra C只面向汽車行業(yè),針對的是汽車行業(yè)的嵌入式開發(fā),后來,從MISRA-C:2004開始,它便擴大了覆蓋范圍,面向其它高安全性系統(tǒng)了。
畢竟,都是嵌入式,都在搞C代碼開發(fā),大哥能比二哥好哪去?所以,Misra C的觸角迅速延伸到安全性至關(guān)重要的許多其他應(yīng)用領(lǐng)域,搞起了獨樂樂不如眾樂樂的大生態(tài)。
周公制禮,天下歸心。規(guī)矩,是讓人心安的,Misra C,也可以讓嵌入式行業(yè)的一眾用戶心安。
3、Misra C規(guī)則原因解讀
Misra C的規(guī)則干巴巴,看官看著打哈哈。
網(wǎng)上有不少對Misra C規(guī)則的解讀,無需灑家再置喙。灑家是覺得,規(guī)則解讀固然重要,但更重要的是,搞清楚Misra C制定這些規(guī)則的原因,咱不僅要知其然,更要知其所以然。
3.1 靈活是陷阱
C語言的靈活性是讓碼農(nóng)對之愛不釋手的原因之一,但是,汝之蜜糖,彼之砒霜。對高手而言,靈活的編程方式和語法規(guī)則是他們發(fā)揮高超水平的蜜糖,對菜鳥來說,便成了處處挖坑的砒霜。
比如if(val++)和if(++val) 這兩種寫法里,它可以同時把if語句和val的累加操作結(jié)合在一起,對高手而言,能省掉一行代碼,確實很靈活,但有時卻會違背了菜鳥碼農(nóng)的本意。
因為這里面有兩個陷阱。
其一,前種寫法是先用當(dāng)前val進(jìn)行判斷,再讓val累加,后一種寫法則是先讓val累加,再用累加后的val判斷。
此外,如果val是個指針,菜鳥又可知,這些累加并非加一,而是加上指針本身的長度呢?
所以,靈活性是一把雙刃劍,刀刃向內(nèi)還是向外全憑本事。
正所謂:二八佳人體似酥,你要是沒那金剛杵,她就暗里教君骨髓枯。
3.2 C語言的運行時檢查能力較弱
灑家曾經(jīng)寫過一段時間的Java,剛開始寫時,便對它能動態(tài)檢查數(shù)組越界贊不絕口,啥時候C代碼也能這樣該有多好?就拿下面來說,
uint8_t Val[10];
…
Val[idx] = 0;
若是運行時idx =10,Val[idx] = 0這個操作便會直接越界到和Val相鄰的變量(假設(shè)為Ino)那里。
假設(shè)您在別的地方給Ino賦了值,根據(jù)其值執(zhí)行不同的動作邏輯,本來一切歲月靜好,結(jié)果神不知、鬼不覺,Ino好端端地突變成了0,您還不得直呼見鬼了!
這種bug,來無影去無蹤,一下就挖個大深坑。你左看看,右瞧瞧,怎么也想不到是鄰居甩的刀!
3.3 電腦的行為同程序員預(yù)期的不同
被baby甩掉的黃曉明曾經(jīng)說過:“我不要你覺得,我要我覺得。。?!?/span>
在C代碼里,也經(jīng)常出現(xiàn)程序員以為這樣,而電腦卻以為那樣的情況。
比如說您寫了下面三行代碼:
uint8_t Pres;
uint16_t Ev_pres;
Ev_pres = (uint16_t)((uint32_t)(Pres * 350) / 255);
您自認(rèn)并非菜鳥,自以為然地在心中嘀咕著:“菜鳥們應(yīng)該想不到,這里面的奧妙之處在于Pres * 350的結(jié)果可能會超出uint16_t的上限65535,數(shù)據(jù)會發(fā)生截斷,所以,把這個結(jié)果加個(uint32_t)就萬無一失了。”
可是,你以為這樣,老板就給你加雞腿了?加個棒槌!
因為,如果Pres=200,你以為Ev_pres=200*350/255=274,但電腦運行后的結(jié)果卻是Ev_pres=17。
為什么呢?聰明的讀者可能看出來了,問題出在(uint32_t)(Pres * 350)這里,Pres * 350在數(shù)據(jù)截斷之后再(uint32_t)已經(jīng)沒有意義了,應(yīng)該改成下面這種寫法:
Ev_pres = (uint16_t)((uint32_t)Pres * 350 / 255);
這個例子也說明,要想和電腦哥倆好,括號的位置很重要!
總結(jié):
搞電子的都知道,代碼寫得好,調(diào)試的活就能省不少,代碼寫得糟,調(diào)試時踩的坑少不了。
所以,按捺住那顆蠢蠢欲動的心,老老實實地遵循規(guī)范標(biāo)準(zhǔn),就能少埋坑,少踩雷,切切實實地碼出質(zhì)量,碼出穩(wěn)定性來。
筒子們,加油!
*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。