2012-12-04 20 views
0

我一直在爲一個開源項目編寫代碼BRL-CAD,這是一個開發已有30多年了的可敬的項目。在修改一個文件時,我注意到了一些奇怪的邏輯,特別是當出現錯誤時使用goto作爲退出函數的一種手段。我讀過的每本書都會傳達一個事實,即每個goto都有一個更好的替代品,但在這種情況下,我同意goto會是最好的選擇。鑑於:在函數內部使用goto作爲退出的手段

tables.c是一個大型文件,其中包含3個函數用於在程序中排序和獲取數據表。下面是檢查錯誤,如果遇到錯誤擊中後藤的代碼片段,整個文件:http://pastebin.com/u4jnNbLu

if ((tabptr=fopen(argv[1], "w+")) == NULL) { //takes place 300-400 lines before the end goto is declared 
    bu_vls_printf(gedp->ged_result_str, "%s: Can't open %s\n", argv[0], argv[1]); 
    status = GED_ERROR; 
    goto end;} 

轉到結束:

end: //frees memory used in function and returns the status(which became an error above) 
    bu_vls_free(&cmd); 
    bu_vls_free(&tmp_vls); 
    bu_ptbl_free(&cur_path); 

    return status; 

是在於使用goto作爲一個功能中止ok?我以前從來沒有想過要這樣做,但對於我來說,將代碼放置在一堆混亂的花括號中,而對於代碼中常常會碰到的/ if/else,以檢查是否有錯誤,似乎更符合邏輯。

+1

C **或** C++?每種語言的最佳實踐都是不同尋常的,例如'goto'在C++中的用處很少(我沒有爭論),而在C語言中,它是跳轉到清理代碼的一種非常標準的方式,就像你請在您的帖子中查看。 – GManNickG

回答

3

這是純C中的一個常見構造(以及一些使用返回值而不是異常錯誤的C++),並且IMO完全可以接受。這將所有的清理保留在一個地方(或者根據函數的結構儘可能地靠近一個地方),並且比嵌套ifs糾結的網絡更容易閱讀和維護,以驗證一切正常工作。