僅僅因為一個特性是用他們選擇的語言提供給程序員的,并不意味著他們應該使用它!在使用C開發嵌入式軟件時尤其如此。雖然C為嵌入式開發人員提供了大量不可或缺的工具,但有8個內置于語言中的關鍵字應該完全避免或僅作為最后手段使用。讓我們簡單探討一下這些保留關鍵字,并理解為什么我們應該盡量減少它們的使用。
保留關鍵字1——auto
auto關鍵字是一個存儲類說明符,它告訴編譯器正在定義的變量的存儲持續時間(范圍)。唯一可以使用該關鍵字的地方是在函數中聲明一個變量,該變量在函數中創建,然后在函數完成時銷毀。因為這在ANSI-C中默認發生在函數的局部變量上,所以使用這個關鍵字是沒有用的!使用它只會讓開發人員感到困惑,因此應該避免。
保留關鍵字2——break
break關鍵字最常用于switch塊的case語句中。這是break語句的完全有效和最好的用法!不幸的是,break也可以用來提前退出循環。這可能是break的有效用法,但是如果循環變得嵌套和復雜,就會有危險。問題變成了使用break可能會產生意想不到的后果,中斷和不執行本來應該運行的代碼?;旧?,break在這種情況下所做的是繞過循環的原始終止表達式。因此,建議僅將break與switch/case語句一起使用,并在循環中使用其他結構來獲得所需的行為。
保留關鍵字3——continue
continue關鍵字與break和goto語句有很多相同的缺點,因為它中斷了代碼流,可能會讓嵌入式開發人員感到困惑。正在修改代碼的迷茫程序員,通常會不小心添加bug!continue語句通過強制執行控制直接轉到循環的測試條件來繞過循環的正常執行。使用continue的唯一有用的地方是發生錯誤時,程序員希望語句序列重新開始。
保留關鍵字4——extern
眾所周知,extern關鍵字只需要很少的介紹,因為默認情況下,C中的所有內容都是隱式extern!extern的問題是它讓一切都全球化了!這是一種糟糕的編程實踐,因為它允許每個函數和變量看到其他人,這不僅會導致可重入性問題,還會允許不相關的函數意外地修改數據。應該盡量減少使用extern,將變量定義為具有最小的范圍,并盡可能多地采用封裝等做法
保留關鍵字5——goto
goto關鍵字是許多電氣工程師轉軟件工程師的舊時代最愛?;氐胶瘮凳骄幊痰臅r代,主要的控制結構是goto關鍵字。該關鍵字允許程序執行跳轉到程序中的指定標簽。goto的問題是它的使用通常會產生讓嵌入式開發人員難以閱讀的代碼!函數和其他流控制語句的使用有助于更好的軟件實現。雖然通常建議永遠不要使用goto,但它唯一有意義的地方是在函數范圍內的錯誤處理程序中使用。
保留關鍵字6——inline
inline關鍵字實際上很酷。你可以將它添加到一個函數的前面(假設你使用的是C99編譯器),而不是將該函數作為編譯代碼中的一個函數來調用,而是將該函數的內容粘貼到位!這意味著,不需要花費時間去調用一個函數,就像函數代碼是在那里寫的一樣!這有兩個主要問題。第一個是由編譯器決定它是否實際內聯代碼!將關鍵字放在函數前面并不能保證編譯器會聽從開發人員的建議。其次,如果編譯器確實內聯了函數,如果函數在整個代碼中被頻繁使用,那么編譯后的代碼的大小可能會失去控制!
保留關鍵字7——restrict
restrict關鍵字是一個僅適用于指針的類型限定符。它是在C99中引入的,允許編譯器對代碼執行優化,前提是被指向的對象只能通過受限指針訪問。不建議使用restrict,因為它可能會產生意想不到的副作用。
保留關鍵字8——register
register關鍵字是開發人員應該避免的另一個存儲類說明符。這個關鍵字的意思是向編譯器建議,應該通過使用一個CPU寄存器來使對象快速可用。這個關鍵字的一個問題是,一旦獲得,它是否會遵從建議或者是否會與其他自動變量一起存儲在堆棧中取決于編譯器。今天的編譯器非常聰明,知道存儲對象和數據的最佳位置,因此最好讓編譯器來決定,而不是再次讓可能正在閱讀代碼并做出錯誤假設的嵌入式開發人員感到困惑。