2023年3月22日 星期三

[C++] goto語法應用於Error Information傳遞

大多數的教科書都說,goto標籤能不用就不用,

它會破壞程式的邏輯,並且難以追蹤行進流程,

但如果好好使用時,其實是相當安全且方便的。

甚至連大廠NI的原廠範例程式碼都是這樣寫的,

原廠大神都在用了,我們也來了解一下吧。

先前寫過一篇 [重構] - 重構Return , 多個Return整合成單一Return ,

主要將多個 return 路徑濃縮成一個,比較好掌握程式的脈絡,

而此篇要討論的方式,其實也可以應用至該篇的情境,

這樣就不必像該篇文章一樣把整段程式碼從頭跑到尾才return,

其中的利弊與情境,可以自行判斷與取捨。


回頭討論 goto 標籤的使用方式。

現在在公司的開發習慣會將function的回傳值都設為int,

主要是用來回傳 Error Code 錯誤碼,

即使運作正常也會回傳0來作為運作正常的回報。

因此我在撰寫一個新的function時,基本結構如下:

建立一個新function時,我會先把名為 result 的int變數宣告為0,

並同時在function結尾建立名為Error的標籤,

在標籤後面執行return result的動作。

因此只要在function內任何一個位置發生錯誤或非預期的情況,

就可以直接透過goto語法,跳過還沒執行的程式碼,

直接回傳result,這樣設計符合單一出入口原則,

也能更有效率的執行程式碼,因為執行尚未執行的部分,

而該部分也不需要透過flag判斷是否該繼續執行(如同此篇文章)。


而該如何呼叫goto呢?

透過 #define 定義一個function : checkErr ,參數為fCall。

fCall傳遞給result,接著result透過三元判斷式判斷是否為Sucess,

這邊Sucess定義為0,而所有的Error Code都定義為負值,

因此只要是負值,就會判定為true,

就會落入 if 判斷式的 true區塊,

進而執行 { goto Error; }。


來看看怎麼使用:

假設這個function匯集了所有硬體啟動的function,

而我們直接使用 checkErr() 去承接 Camera function 的回傳值,

假設回傳值非0 ,即代表初始化失敗,這樣就會直接啟動goto,

直達Error標籤,略過其他硬體的啟動function,

增加程式碼的執行效率。

以下為InitialCamera()的內容:


此時在這個包裝原廠API的function中,就可以回傳自定義的Error Code,

不但能統整各個廠商的 Error Code,作為開發者也比較容易進行管理。


提供一個goto的使用情境給大家參考。


沒有留言:

張貼留言

社會新鮮人如何投資?

我的觀點是,在 沒有很多 本錢 的情況下, 別寄望每個月幾千元放到股票或者最近很夯的高股息ETF就能讓你致富, 先投資自己,讓自己的本業收入提高吧。