《Design by Contract for Embedded Software》 翻譯( 二 )


In a typical embedded system, on the other hand, the same failed malloc() probably should be flagged as a bug. That’s because embedded systems offer much fewer excuses to run out of memory, so when it happens, it’s typically an indication of a flaw. You cannot really recover from it. Exiting other applications is not an option. Neither is saving data to a disk and exit. Whichever way you look at it, it’s a bug no different really from overflowing the stack, dereferencing a NULL pointer, or overrunning an array index. Instead of bending over backwards in attempts to handle this condition in software (as you would on the desktop), you should concentrate first on finding the root cause and then fixing the problem. (I would first look for a memory leak, wouldn’t you?)

另一方面,在一個典型的嵌入式系統中,同樣失敗的 malloc() 可能應該被標記為一個錯誤 。這是因為嵌入式系統提供的內存耗盡的借口要少得多 , 所以當它發生時 , 它通常是一個缺陷的跡象 。你無法真正從中恢復 。退出其他應用程序不是一種選擇 。將數據保存到磁盤并退出也不是一種選擇 。無論你從哪方面看 , 這都是一個錯誤 , 與堆棧溢出、解讀 NULL 指針或超限數組索引沒有什么區別 。與其在軟件中彎腰試圖處理這種情況(就像在桌面上一樣),你應該首先集中精力找到根本原因,然后解決問題 。(如我首先會尋找內存泄漏,你會嗎?)
The main point here is that many situations traditionally handled as exceptional conditions in general-purpose computing are in fact bugs in embedded systems. In other words, the specifics of embedded systems (computers dedicated to a single, well-defined purpose) allow you to considerably simplify the embedded software by flagging many situations as bugs (that you don’t need to handle) rather than exceptional conditions (that you do need to handle). The correct distinction between these two situations always depends on the context, so you should not blindly transfer the rules of thumb from other areas of programming to embedded real-time systems. Instead, I propose that you critically ask yourself the following two probing questions: “Can a given situation legitimately arise in this particular system?” and “If it happens, is there anything specific that needs to or can be done in the software?” If the answer to either of these questions is “yes,” then you should handle the situation as an exceptional condition; otherwise, you should treat the situation as a bug.
這里的主要觀點是 , 許多在傳統的通用計算中作為異常 (特殊情況) 處理的情況,在嵌入式系統中實際上表現為錯誤 。換句話說,嵌入式系統(專門用于單一的、定義明確的用途的計算機)的特性允許你通過將許多情況標記為 bug(你不需要處理)而不是異常(你需要處理)來大大簡化嵌入式軟件 。這兩種情況的正確區分總是取決于上下文,所以你不應該盲目地將其他編程領域的經驗法則轉移到嵌入式實時系統中 。相反,我建議你批判性地問自己以下兩個探究性問題 。"在這個特定的系統中 , 一個特定的情況會合法地出現嗎?"和 "如果它發生了,在軟件中是否有任何具體的需要或可以做的事情?" 如果這兩個問題的答案都是 "是",那么你就應該把這種情況作為一種異常來處理;否則,你就應該把這種情況作為一個錯誤來處理 。
The distinction between errors and exceptional conditions in any type of software (not just firmware) is important, because errors require the exact opposite programming strategy than exceptional conditions. The first priority in dealing with errors is to detect them as early as possible. Any attempt to handle a bug (as you would an exceptional condition) results in unnecessary complications of the code and either camouflages the bug or delays its manifestation. (In the worst case, it also introduces new bugs.) Either way, finding and fixing the bug will be harder.
在任何類型的軟件(不僅僅是固件)中 , 區分錯誤和異常是很重要的 , 因為錯誤需要與異常完全相反的編程策略 。處理錯誤的首要任務是盡可能早地發現它們 。任何試圖處理錯誤的行為(就像處理特殊情況一樣)都會導致代碼不必要的復雜化,要么掩蓋錯誤,要么延遲其表現 。(在最壞的情況下,它還會引入新的錯誤 。) 無論怎樣,發現和修復錯誤都會更難 。
Design by Contract (DbC)契約設計(DbC)
And here is where the Design by Contract (DbC) philosophy comes in. DbC, pioneered by Bertrand Meyer, views a software system as a set of components whose collaboration is based on precisely defined specifications of mutual obligations—the contracts.1 The central idea of this method is to inherently embed the contracts in the code and validate them automatically at run time. Doing so consistently has two major benefits: 1) It automatically helps detect bugs (as opposed to “handling” them), and 2) It is one of the best ways to document code.

推薦閱讀