编者按:C语言是开发嵌入式应用的主要工具,然而C语言并非是专门为嵌入式系统设计,相当多的嵌入式系统较一般计算机系统对软件安全性有更苛刻的要求。1998年,MISRA指出,一些在C看来可以接受,却存在安全隐患的地方有127处之多。2004年,MISRA对C的限制增加到141条。嵌入式系统应用工程师借用计算机专家创建的C语言,使嵌入式系统应用得以飞速发展,而MISRAC是嵌入式系统应用工程师对C语言嵌入式应用做出的贡献。如今MISRAC已经被越来越多的企业接受,成为用于嵌入式系统的C语言标准,特别是对安全性要求极高的嵌入式系统,软件应符合MISRA标准。从本期开始,本刊将分6期,与读者共同学习MISRAC。第一讲:“‘安全第一’的C语言编程规范”,简述MISRAC的概况。第二讲:“跨越数据类型的重重陷阱”,介绍规范的数据定义和操作方式,重点在隐式数据类型转换中的问题。第三讲:“指针、结构体、联合体的安全规范”,解析如何安全而高效地应用指针、结构体和联合体。第四讲:“防范表达式的失控”,剖析MISRAC中关于表达式、函数声明和定义等的不良使用习惯,最大限度地减小各类潜在错误。第五讲:“准确的程序流控制”,表述C语言中控制表达式和程序流控制的规范做法。第六讲:“构建安全的编译环境”,讲解与编译器相关的规范编写方式,避免来自编译器的隐患。“安全第一”的C语言编程规范C/C++语言无疑是当今嵌入式开发中最为常见的语言。早期的嵌入式程序大都是用汇编语言开发的,但人们很快就意识到汇编语言所带来的问题——难移植、难复用、难维护和可读性极差。很多程序会因为当初开发人员的离开而必须重新编写,许多程序员甚至连他们自己几个月前写成的代码都看不懂。C/C++语言恰恰可以解决这些问题。作为一种相对“低级”的高级语言,C/C++语言能够让嵌入式程序员更自由地控制底层硬件,同时享受高级语言带来的便利。对于C语言和C++语言,很多的程序员会选择C语言,而避开庞大复杂的C++语言。这是很容易理解的——C语言写成的代码量比C++语言的更小些,执行效率也更高。ᇍѢᑣਬᴹ䇈ˈ㛑ᎹⱘҷⷕᑊϡㄝѢ³ད´ⱘҷⷕDŽ³ད´ҷⷕⱘᣛᷛᕜˈࣙᣀᯧ䇏ǃᯧ㓈ᡸǃᯧ⿏ỡৃ䴴ㄝDŽ݊Ёˈৃ䴴ᗻᇍጠܹᓣ㋏㒳䴲ᐌ䞡㽕ˈᇸ݊ᰃ䙷ѯᇍᅝܼᗻ㽕∖ᕜ催ⱘ㋏㒳Ёˈབ亲㸠఼ǃ≑䔺ᎹϮࠊЁDŽ䖭ѯ㋏㒳ⱘ⡍⚍ᰃ˖া㽕Ꮉ᳝أᏂˈህ᳝ৃ㛑䗴៤䞡ᤳ༅㗙ҎਬӸѵDŽϔϾϡᆍᯧߎ䫭ⱘ㋏㒳ˈ䰸њ㽕᳝ᕜདⱘ⹀ӊ䆒䅵˄བ⬉⺕ݐᆍᗻ˅ˈ䖬㽕᳝ᕜعໂ㗙䇈³ᅝܼ´ⱘᑣDŽ✊㗠ˈᕜᇥ᳝ᑣਬⶹ䘧ҔМḋⱘᑣᰃᅝܼⱘᑣDŽᕜᑣাᰃ㸼䴶Ϟৃҹᑆ⌏ˈ䖬ᄬⴔ䞣ⱘ䱤ᙷDŽᔧ✊ˈ䖭݊Ёг᳝C䇁㿔㞾䑿ⱘॳDŽЎC䇁㿔ᰃϔ䮼䲒ҹᥠᦵⱘ䇁㿔ˈ݊♉⌏ⱘ㓪ᮍᓣ䇁⊩㾘߭ᇍѢϔϾᮄᴹ䇈ᕜৃ㛑Ӯ៤Ўᴎ݇䞡䞡ⱘ䱋䰅DŽৠᯊˈC䇁㿔ⱘᅮН䖬ᑊϡᅠܼˈेՓᰃ䰙䗮⫼ⱘC䇁㿔ᷛޚˈг䖬ᄬⴔᕜᅠܼᅮНⱘഄᮍDŽ㽕∖᠔᳝ⱘጠܹᓣᑣਬ䛑៤ЎC䇁㿔ϧᆊˈ䙓ᓔ᠔᳝ৃ㛑ᏺᴹॅ䰽ⱘ㓪ᮍᓣˈᰃϡ⦄ᅲⱘDŽ᳔དⱘᮍ⊩ᰃ᳝ϔϾ䩜ᇍᅝܼᗻⱘC䇁㿔㓪㾘㣗ˈਞ䆝ᑣਬ䆹བԩخDŽ1MISRAC㾘㣗1994ᑈˈ㣅៤ゟњϔϾিخ≑䔺ᎹϮ䕃ӊৃ䴴ᗻ㘨ড়Ӯ˄TheMotorIndustrySoftwareReliabilityAssociationˈҹϟㅔ⿄MISRA˅ⱘ㒘㒛DŽᅗᰃ㟈Ѣणࡽ≑䔺ॖଚᓔথᅝܼৃ䴴ⱘ䕃ӊⱘ䎼णӮˈ݊៤ਬࣙᣀ˖AB≑䔺⬉ᄤǃ㔫ᄮ≑䔺ǃᆒ߽≑䔺ǃ⽣⡍≑䔺ǃ᥋䉍≑䔺ǃ䏃㰢݀ৌǃLotus݀ৌǃMIRA݀ৌǃRicardo݀ৌǃTRW≑䔺⬉ᄤǃ߽ݍᄺ⽣⡍VISTEON≑䔺㋏㒳݀ৌDŽ㒣䖛њಯᑈⱘⷨおޚˈMISRAѢ1998ᑈথᏗњϔϾ䩜ᇍ≑䔺ᎹϮ䕃ӊᅝܼᗻⱘC䇁㿔㓪㾘㣗²²lj≑䔺ϧ⫼䕃ӊⱘC䇁㿔㓪ᣛफNJ(GuidelinesfortheUseoftheCLanguageinVehicleBasedSoftware)ˈ᳝݅127ᴵ㾘߭ˈ⿄ЎMISRAC:1998DŽC䇁㿔ᑊϡУ䰙ᷛޚDŽ䰙ᷛޚ࣪㒘㒛˄InternationalOrganizationofStandardization,ㅔ⿄ISO˅ⱘ³ᷛޚC䇁㿔´㒣ग़њҢC90ǃC96ࠄC99ⱘবࡼDŽԚᰃˈጠܹᓣᑣਬᕜ䲒ᇚISOᷛޚᔧ㓪ݭᅝܼҷⷕⱘ㾘㣗DŽϔᰃЎᷛޚC䇁㿔ᑊϡᰃ䩜ᇍҷⷕᅝܼⱘˈгᑊϡᰃϧ䮼Ўጠܹᓣᑨ⫼䆒䅵ⱘ˗ѠᰃЎ³ᷛޚC䇁㿔´ᑲњˈᕜ䲒᪡DŽMISRAC:1998㾘㣗ⱘѻ⫳ᙄᙄᓹ㸹њ䖭ᮍ䴶ⱘぎⱑDŽ䱣ⴔᕜ≑䔺ॖଚᓔྟফMISRAC㓪㾘㣗ˈMISRAC:1998г៤Ў≑䔺ᎹϮЁ᳔Ў㨫ৡⱘ᳝݇ᅝܼᗻⱘC䇁㿔㾘㣗DŽ2004ᑈˈMISRAߎ⠜њ䆹㾘㣗ⱘᮄ⠜ᴀ²²MISRAC:2004DŽᮄ⠜ᴀЁˈ䖬ᇚ䴶ⱘᇍ䈵⬅≑䔺ᎹϮᠽࠄ᠔᳝ⱘ催ᅝܼᗻ㽕∖˄Critical˅㋏㒳DŽMISRAC:2004Ёˈ᳝݅ᔎࠊ㾘߭121ᴵˈ㤤㾘߭20ᴵˈᑊߴ䰸њ15ᴵᮻ㾘߭DŽӏԩヺড়MISRAC:2004㓪㾘㣗ⱘҷⷕ䛑ᑨ䆹ϹḐⱘ䙉ᕾ121ᴵᔎࠊ㾘߭ⱘ㽕∖ˈᑊᑨ䆹ᴵӊܕ䆌ⱘᚙމϟሑৃ㛑ヺড়20ᴵ㤤㾘߭DŽMISRAC:2004ᇚ݊141ᴵ㾘߭ߚЎ21Ͼ㉏߿ˈ↣ϔᴵ㾘߭ᇍᑨϔᴵ㓪ޚ߭DŽ䆺㒚ᚙމབ㸼1᠔߫DŽ㸼1MISRAC:2004㾘߭ߚ㉏᳔߱ˈMISRAC:1998㓪㾘㣗ⱘᓎゟᰃЎњᔎ≑䔺ᎹϮ䕃ӊⱘᅝܼᗻDŽৃ㛑䗴៤≑䔺џᬙⱘॳ᳝ᕜˈབ1᠔⼎ˈ䆒䅵ࠊ䗴ᯊඟϟⱘ䱤ᙷ㑺ऴᘏ᭄ⱘ15%ˈ݊Ёгࣙᣀ䕃ӊⱘ䆒䅵ࠊ䗴DŽMISRAC:1998ህᰃЎњޣᇣ䖭䚼ߚ䱤ᙷ㗠ࠊᅮⱘDŽMISRAC㓪㾘㣗ⱘߎ䖢ড়њᕜ≑䔺ॖଚⱘ䳔㽕ˈЎϔᮺॖଚᑣ䆒䅵Ϟߎ⦄њ䯂乬ˈ⫼ᴹ㸹ᬥⱘ䌍⫼ᇚⳌᔧৃ㾖DŽ1999ᑈ7᳜22᮹ˈ䗮⫼≑䔺݀ৌ˄GeneralMotors˅ህ᳒㒣Ў݊䕃ӊ䆒䅵ϞⱘϔϾ䯂乬ˈ㹿䖿ীಲ350ϛ䕚Ꮖ㒣ߎॖⱘ≑䔺ˈᤳ༅Пৃᛇ㗠ⶹDŽMISRAC㾘㣗ϡҙ≑䔺ᎹϮᓔྟ᱂ঞˈгৠᯊᕅડࠄњጠܹᓣᓔথⱘ݊ҪᮍDŽጠܹᓣᅲᯊ᪡㋏㒳Nj&26,,ⱘ2.52⠜ᴀ㱑✊Ꮖ㒣Ѣ2000ᑈ䗮䖛њ㕢㟾ぎㅵ⧚ሔ˄FAA˅ⱘᅝܼ䅸䆕ˈԚ2003ᑈ㗙ህḍMISRAC:1998㾘㣗জᇍ⑤ⷕخњⳌᑨⱘׂᬍˈབᇚif((pevent-OSEventTbl[y]&=~bitx)==0){«}ⱘݭ⊩ˈᬍݭ៤pevent-OSEventTbl[y]&=~bitx;if(pevent-OSEventTbl[y]==0){«}থᏗњ2.62ⱘᮄ⠜ᴀˈᑊᅷ⿄݊⑤ҷⷕ99ˁヺড়MISRAC:1998㾘㣗DŽϔϾᑣ㛑ヺড়MISRAC㓪㾘㣗ˈϡҙ䳔㽕ᑣਬᣝ✻㾘㣗㓪ˈ㓪䆥఼г䳔㽕ᇍ᠔㓪䆥ⱘҷⷕ䖯㸠㾘߭ẔᶹDŽ⦄ˈᕜ㓪䆥఼ᓔথଚ䛑ᇍMISRAC㾘㣗᳝њᬃᣕˈ↨བIARⱘ㓪䆥఼ህᦤկњᇍMISRAC:1998㾘㣗127ᴵ㾘߭ⱘẔᶹࡳ㛑DŽ2MISRACᇍᅝܼᗻⱘ⧚㾷MISRAC:2004ⱘϧᆊӀ䛑ᴹ㞾Ѣ䕃ӊᎹϮ㗙≑䔺ᎹϮⱘⶹৡ݀ৌˈ㾘㣗ⱘࠊᅮϡҙҙڣ䖛এϔḋሔ䰤Ѣ≑䔺ᎹϮⱘC䇁㿔㓪ˈৠᯊ䖬⎉Ⲫњ݊Ҫ催ᅝܼᗻ㋏㒳DŽ1≑䔺џᬙॳߚᏗMISRAC:2004䅸ЎCᑣ䆒䅵Ёᄬⱘ亢䰽ৃ㛑⬅5Ͼᮍ䴶䗴៤˖ᑣਬⱘ༅䇃ǃᑣਬᇍ䇁㿔ⱘ䇃㾷ǃᑣਬᇍ㓪䆥఼ⱘ䇃㾷ǃ㓪䆥఼ⱘ䫭䇃䖤㸠ߎ䫭(runtimeerrors)DŽᑣਬⱘ༅䇃ᰃৌぎ㾕ᛃⱘDŽᑣਬᰃҎˈ䲒ܡӮ⢃䫭䇃DŽᕜ⬅ᑣਬ⢃ϟⱘ䫭䇃ৃҹ㹿㓪䆥఼ঞᯊഄ㑴ℷ˄བ䬂ܹ䫭䇃ⱘব䞣ৡㄝ˅ˈԚг᳝ᕜӮ䗗䖛㓪䆥఼ⱘẔᶹDŽⳌֵӏԩϔϾᑣਬ䛑᳒㒣⢃䖛ᇚ³´䇃ݭ៤³´ⱘ䫭䇃ˈ㓪䆥఼ৃ㛑ϡӮ䅸Ўif(x=y)ᰃϔϾᑣਬⱘ༅䇃DŽݡВϾ՟ᄤˈᆊ䛑ⶹ䘧++䖤ㅫヺDŽ؛བ᳝ϟ䴶ⱘᣛҸ˖i=3;SULQWI³G´L䕧ߎᑨ䆹ᰃᇥ˛བᵰᰃ:SULQWI³G´Lਸ਼˛བᵰᬍ៤-i++ਸ਼˛i+++iਸ਼˛i+++++iਸ਼˛㒱᭄ᑣਬᘤᗩᏆ㒣㊞⍖њDŽMISRAC:2004ЁˈӮᯢ⹂ᣛߎ++--䖤ㅫヺϡᕫ݊Ҫ䖤ㅫヺ⏋ড়Փ⫼DŽC䇁㿔䴲ᐌ♉⌏ˈᅗ㒭њᑣਬ䴲ᐌⱘ㞾⬅DŽԚџᚙ᳝ད᳝ണˈ㞾⬅䍞ˈ⢃䫭䇃ⱘᴎӮгህ䍞DŽབᵰ䇈᳝ѯ䫭䇃ᰃᑣਬ᮴ᖗП༅ⱘ䆱ˈ䙷МЎᑣਬᇍC䇁㿔ᴀ䑿ᰃ㓪䆥఼⡍ᗻⱘ䇃㾷㗠䗴៤ⱘ䫭䇃ህᰃ³ᯢ´ⶹᬙ⢃њDŽC䇁㿔᳝ϔѯὖᗉᕜ䲒ᥠᦵˈ䴲ᐌᆍᯧ䗴៤䇃㾷ˈབ㸼䖒ᓣⱘ䅵ㅫDŽ䇋ⳟϟ䴶䖭ᴵ䇁হ˖if(ishigh&&(x==i++))ᕜᑣਬ䅸Ўᠻ㸠њ䖭ᴵᣛҸৢˈiব䞣ⱘؐህӮ㞾ࡼࡴ1DŽԚⳳℷⱘᚙމབԩਸ਼˛MISRAЁ᳝ϔᴵ㾘߭˖䘏䕥䖤ㅫヺ&&||ⱘে᪡᭄ϡᕫᏺ᳝ࡃ⫼˄sideeffect˅*ˈህᰃЎњ䙓ܡ䖭⾡ᚙމϟৃ㛑ߎ⦄ⱘ䯂乬DŽ*᠔䇧ᏺ᳝ࡃ⫼ˈህᰃᣛᠻ㸠ᶤᴵ䇁হᯊӮᬍব䖤㸠⦃๗ˈབᠻ㸠x=i++ПৢˈiⱘؐӮথ⫳ব࣪DŽˈϡৠ㓪䆥఼ᇍৠϔ䇁হⱘ໘⧚ৃ㛑ᰃϡϔḋⱘDŽ՟བᭈൟব䞣ⱘ䭓ᑺˈϡৠ㓪䆥఼ⱘ㾘ᅮህϡৠDŽ䖭ህ㽕∖ᑣਬϡҙ㽕⏙ἮC䇁㿔ᴀ䑿ⱘ⡍ᗻˈ䖬㽕њ㾷᠔⫼ⱘ㓪䆥఼ˈ䲒ᑺᕜDŽ䖬᳝ѯ䫭䇃ᰃ⬅㓪䆥఼˄㗙䇈ᰃ㓪ݭ㓪䆥఼ⱘᑣਬ˅ᴀ䑿䗴៤ⱘDŽ䖭ѯ䫭䇃ᕔᕔ䕗䲒থ⦄ˈ᳝ৃ㛑ӮϔⳈᄬ⬭᳔ৢⱘᑣЁDŽ䖤㸠䫭䇃ᣛⱘᰃ䙷ѯ䖤㸠ᯊߎ⦄ⱘ䫭䇃ˈབ䰸᭄ㄝѢ䳊ǃᣛ䩜ഄഔ᮴ᬜㄝ䯂乬DŽ䖤㸠䫭䇃䇁⊩Ẕᶹᯊϔ㠀᮴⊩থ⦄ˈԚϔᮺথ⫳ᕜৃ㛑ᇐ㟈㋏㒳ዽDŽ՟བ˖#defineNULL0««char*p;p=NULL;SULQWI³/RFDWLRQRILVG\Q´S䇁⊩Ϟ≵᳝ӏԩ䯂乬ˈԚᶤѯ㋏㒳Ϟैৃ㛑䖤㸠ߎ䫭DŽC䇁㿔ৃҹѻ⫳䴲ᐌ㋻ޥǃ催ᬜⱘҷⷕˈϔϾॳህᰃC䇁㿔ᦤկⱘ䖤㸠䫭䇃Ẕᶹࡳ㛑ᕜᇥˈ㱑✊䖤㸠ᬜ⥛ᕫҹᦤ催ˈԚг䰡Ԣњ㋏㒳ⱘᅝܼᗻDŽ᳝হ䆱䇈ᕫདˈ³ℷ⹂ⱘ㾖ᗉ䞡Ѣϔߛ´DŽMISRAC㾘㣗ᇍѢጠܹᓣᑣਬᴹ䆆ˈϔϾᕜ䞡㽕ⱘᛣНህᰃᦤկ㒭ҪӀϔѯᓎ䆂ˈ䅽ҪӀ䗤⏤ᷥゟϔѯདⱘ㓪дᛃ㓪ᗱ䏃ˈ᜶᜶ᨦᓗ䙷ѯৃ㛑ᄬ亢䰽ⱘ㓪㸠Ўˈ㓪ݭߎЎᅝܼǃعໂⱘҷⷕDŽ↨བˈᕜጠܹᓣᑣਬ䛑Ӯᗑ⬹⊼䞞ⱘ䞡㽕ᗻˈԚ䖭ḋⱘخ⊩Ӯ䰡Ԣᑣⱘৃ䇏ᗻˈгӮ㒭ᇚᴹⱘ㓈ᡸ⿏ỡᏺᴹ亢䰽DŽጠܹᓣᑣਬ㒣ᐌ㽕㾺ࠄ⾡ⱘ㓪䆥఼ˈ㗠ᕜCᑣϡৠ㓪䆥఼ϟⱘ໘⧚ᰃϡϔḋⱘDŽMISRAC:2004᳝ϔᴵᔎࠊ㾘߭ˈ㽕∖ᑣਬᡞ᠔᳝㓪䆥఼⡍ᗻⳌ݇ⱘC䇁㿔㸠Ў䆄ᔩϟᴹDŽ䖭ḋᑣਬخ⿏ỡᎹᯊˈ亢䰽ህ䰡ԢњDŽ3MISRACⱘ䋳䴶ᬜᑨᑣਬৃ㛑Ӯᢙᖗ䞛⫼MISRAC:2004㾘㣗ӮᇍҪӀⱘᑣ᳝䋳䴶ᕅડˈ↨བৃ㛑Ӯᕅડҷⷕ䞣ǃᠻ㸠ᬜ⥛ᑣৃ䇏ᗻㄝDŽᑨ䆹䇈ˈ䖭⾡ᢙᖗϡ᮴䘧⧚DŽ㒉㾖141ᴵMISRAC:2004㓪㾘㣗ˈ᭄ⱘ㾘߭ᑊϡӮᇍᑣⱘҷⷕ䞣ǃᠻ㸠ᬜ⥛ৃ䇏ᗻ䗴៤ҔМⱘᕅડ˗ϔ䚼ߚ㾘߭ৃ㛑Ӯҹࡴᄬټ఼ⱘऴ⫼ぎ䯈ЎҷӋᴹࡴᠻ㸠ᬜ⥛ˈ㗙ࡴҷⷕⱘৃ䇏ᗻ˗Ԛᰃˈг⹂ᅲᄬⴔϔѯ㾘߭ৃ㛑Ӯ䰡Ԣᑣⱘᠻ㸠ᬜ⥛DŽϔϾൟⱘ՟ᄤህᰃ݇Ѣ㘨ড়ԧⱘՓ⫼DŽMISRAC:2004᳝ϔᴵ㾘߭ᯢ⹂ᣛߎ˖ϡᕫՓ⫼㘨ড়ԧDŽ䖭ᰃЎˈ㘨ড়ԧⱘᄬټᮍᓣ˄བԡ฿ܙǃᇍ唤ᮍᓣǃԡ乎ᑣㄝ˅Ϟˈ⾡㓪䆥఼ⱘ໘⧚ৃ㛑ϡৠDŽ↨བˈ㒣ᐌӮ᳝ᑣਬ䖭ḋخ˖ϔ䖍ᇚ䞛䲚ᕫࠄⱘ᭄ᣝ✻ᶤ⾡㉏ൟᄬܹϔϾ㘨ড়ԧˈ㗠ৠᯊজ䞛⫼ϔ⾡᭄㉏ൟᇚ䆹᭄䇏ߎDŽབϟ䴶䖭↉ᑣ˖typedefunion{uint32_tword;uint8_tbytes[4];}word_msg_t;unit32_tread_word_big_endian(void){word_msg_ttmp;tmp.bytes[0]=read_byte();tmp.bytes[1]=read_byte();tmp.bytes[2]=read_byte();tmp.bytes[3]=read_byte();return(tmp.word);}ॳ⧚Ϟˈ䖭⾡㘨ড়ԧᕜڣᰃϔϾ⹀ӊϞⱘঠষRAMᄬټ఼DŽԚᑣਬᖙ乏⏙Ἦˈ䖭⾡خ⊩ᰃ᳝亢䰽ⱘDŽMISRAC:2004㤤⫼ϟ䴶䖭⾡ᮍ⊩ᴹخ˖uint32_tread_word_big_endian(void){uint32_tword;word=((unit32_t)read_byte())2