iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 26
0
自我挑戰組

30 Days 如何把 C 語言偽裝成高階語言 OWO /系列 第 27

Day 26: 例外處理系列:研究進行中 :優化:不再需要【回傳值必須作錯誤碼處理的約定】

▌第一次閱讀本系列的,可以先看:

本系列的大綱 傳送門


▌第一次閱讀例外處理系列,可以先看:

例外處理系列 開始第一篇 傳送門


本例外處理系列為【實驗性質】,研究進行中......。

  • 增加了整數變數 isItError 來表示是否發生錯誤。
  • 基於使用了 isItError 的原因,不再需要回傳值必須作錯誤碼處理的約定
    • 更改了所有巨集的內部結構、實現。
    • 更改了測試用函數的內部結構、實現。
  • throw 語意與真實的語意不同,改名為 check
  • 更改了 trythrow(新的check) 的使用方式
    • 由以函數作參數,檢查回傳值。更改為函數執行後,檢查 isItError 的狀態、數值。
  • 加入了新的 throw 來拋出錯誤(設 isItError 為一、退出函數)。
  • back 巨集的參數 back_ex 改名為 back_point

【增加】:

  • 增加了 isItError 來表示是否發生錯誤。
int isItError = 0;
  • 加入了新的 throw 來拋出錯誤(設 isItError 為一、退出函數)。
#define throw(...) \
\
isItError = 1; \
return __VA_ARGS__;

【更改】:

  • 更改 trythrow(新的check) 的使用方式
    • 由檢查函數的回傳值,更改為函數執行後,檢查 isItError 的狀態、數值。
#define try(ex_name, back_point) \
\
if(isItError){ \
	error_place = #back_point; \
	goto ex_name;\
} \
back_point: \
#define check(...) \
\
if(isItError){ \
	return __VA_ARGS__; \
}
  • 更改了 catch 的實現
#define catch(ex_name) \
\
if(!isItError) return 0; \
ex_name:
  • 更改了 back 的實現
#define back(back_point) \
\
if(!strcmp(error_place, #back_point)){ \
	isItError = 0; \
	goto back_point; \
}
  • 更改了測試用函數的內部結構、實現。
void can_not_be_negative(double input) {
	if (input < 0) {
		throw();
	}
}
double my_sqrt(double input) {
	can_not_be_negative(input); check(0.0); 
	return sqrt(input);
}

【使用例子】:

int main() {

	my_sqrt(-10); try(ex_can_not_be_negative, ex1);
	my_sqrt(20); try(ex_can_not_be_negative, ex2);
	my_sqrt(-30); try(anthor_ex, ex3);

	/*... any things ...*/

	system("pause");

	catch (ex_can_not_be_negative) {
		printf("[ex_can_not_be_negative] exception is happened!\n");
		printf("Input can't no be negative.\n");
	}
	back(ex1); back(ex2);

	catch (anthor_ex) {
		printf("[anthor_ex] exception is happened!\n");
		printf("Input can't no be negative.\n");
	}
	back(ex3);
}
[ex_can_not_be_negative] exception is happened!
Input can't no be negative.
[anthor_ex] exception is happened!
Input can't no be negative.
Press any key to continue . . .

【問題】:

  • try 需要設置返回點,麻煩。
  • catch 結束後須加上 backback 需要對應、適合的返回點,
    • 多過返回點需要多個 back ,使用方式繁複。
  • 因應拋出的錯誤無分類型,無法拋出多個種類的錯誤。
  • goto 是短程跳躍,無法直接回到最適當的位置。
    • 這可以彌補,並且未必是缺點。

主要問題是無法自動設置及判斷返回點,導致使用上的麻煩。


不再需要【回傳值必須作錯誤碼處理的約定】是一個很大的優化,

撰寫函數容易了,可讀性也會比較好。


繼續研究。..


上一篇
Day 25: 例外處理系列:研究進行中:優化:一個 catch 可對應多個 try
下一篇
Day 27: 例外處理系列:研究進行中 :大量優化、黑魔法
系列文
30 Days 如何把 C 語言偽裝成高階語言 OWO /31

尚未有邦友留言

立即登入留言