※ 本文為 ChiChi7.bbs. 轉寄自 ptt.cc 更新時間: 2017-10-13 01:00:36
看板 Gossiping
作者 標題 Re: [問卦] C語言沒人用goto?
時間 Thu Oct 12 06:56:41 2017
※ 引述《bencert (根本ㄏㄏ)》之銘言:
: 小弟我剛剛想起來
: C語言有種用法是goto
: 但是上程式設計的課老師也跳過不教
: 我看也沒人用過goto
: 有沒有C語言GOTO的八卦?
: -----
: Sent from JPTT on my Samsung SM-G930F.
八卦是,ptt 的程式碼裡面也有使用 goto.
在 c99 spec 裡面,goto 是定義在 6.8.6 Jump Statements
其中的 6.8.6.1 The goto statement. 作用就是提供一個無條件
跳躍的功能. Spec 裡面給的範例是這個:
/* ... */
goto first_time;
for (;;) {
// determine next operation
/* ... */
if (need to reinitialize) {
// reinitialize-only code
/* ... */
// general initialization code
continue;
// handle other operations
/* ... */
}
基本上這樣的形式,還是能夠做簡化的,只要把 first_time label
下面的 initialization code 做成一個 function 去 call,就不用
用到 goto label 了。
下面的 initialization code 做成一個 function 去 call,就不用
用到 goto label 了。
至於會使用到 goto 的一些理由,在要求結構化程式碼,以及編譯器
優化隨著技術進步的關係,也越來越站不住腳了。
至於為什麼台灣都有種無腦不使用 goto 的教條呢?因為當老師的
只會舉一些鳥蛋的例子啊:
int main() {
int i = 0;
loop:
printf("%d\n", i++);
if (i < 10)
goto loop;
}然後就沒了。
然後就沒了。
然後就沒了。
目前比較大的 C 語言專案中用到 goto,幾乎都是在做 exception handling 的部分,
因為 C 語言的特性,出錯了的時候,很多動態配置的記憶體會需要回收掉,
要不然會造成 memory leak。這時候 goto 就變得很方便。例如說 CPython
的這段程式碼:
要不然會造成 memory leak。這時候 goto 就變得很方便。例如說 CPython
的這段程式碼:
static void
TaskObj_finalize(TaskObj *task)
{
/* ... */
if (task->task_state != STATE_PENDING ||
!task->task_log_destroy_pending) {
goto done;
}/* ... */
context = PyDict_New();
if (context == NULL) {
goto finally;
message = PyUnicode_FromString("Task was destroyed...");
if (message == NULL) {
goto finally;
/* ... */
finally:
Py_XDECREF(context);
Py_XDECREF(message);
/* Restore the saved exception. */
PyErr_Restore(error_type, error_value, error_traceback);
done:
FutureObj_finalize((FutureObj*)task);
}
https://github.com/python/cpython/blob/master/Modules/_asynciomodule.c#L1711
cpython/_asynciomodule.c at master · python/cpython · GitHub
cpython - The Python programming language ...
cpython - The Python programming language ...
這邊就能很明顯看出 goto 的作用啦,第一個
goto done
,因為還沒有allocate context 或是 message,所以不需要去做善後的工作,如果這時候
觸發這個 goto 的話,就直接到底就好。
但是如果遇到 context 或是 message allocate 失敗的話,因為已經有
allocate 一些資源,就必須要跳到 finally 去把這些資源給清空以及還原。
在 Linux kernel 裡面也有許多需要做 exception handling 的部分,
因此也大量的使用了 goto, 但不太會有教科書上那種錯誤範例的使用方式
在裡面就是了。
最後,pttbbs 本身也有用啊 XDDD
https://github.com/ptt/pttbbs/blob/master/mbbsd/brc.c#L689
更多 goto,請參考 wikipedia:
https://en.wikipedia.org/wiki/Goto#Common_usage_patterns_of_Goto
Goto - Wikipedia GoTo (goto, GOTO, GO TO or other case combinations, depending on the programming language) is function call normally returns control. The jumped-to locations are usually identified using labels, though some languages use line numbers. At the machine code level, a goto is a form of branch or jump sta ...
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.113.63.78
※ 文章代碼(AID): #1Ptg6po0 (Gossiping)
※ 文章網址: https://www.ptt.cc/bbs/Gossiping/M.1507762611.A.C80.html
※ 編輯: grapherd (140.113.63.78), 10/12/2017 06:58:05
--
推 : 認真文給推1F 10/12 07:02
→ : 語義不明 就不要怪人們亂用2F 10/12 07:02
推 : 認真給推 我都goto 來goto去 只有自己懂3F 10/12 07:09
→ soga0806 …
推 : push5F 10/12 07:18
推 : 認真給推!6F 10/12 07:41
推 : 快推 不然人家會以為我看不懂7F 10/12 07:44
→ : 通常是用在early exit 之類的,但是因為有很多亂用的8F 10/12 07:55
→ : 人所以教學上會先教不要用,你如果看過一些光怪陸離
→ : C/C++ 使用方法就會覺得教不要用是對的
→ : 人所以教學上會先教不要用,你如果看過一些光怪陸離
→ : C/C++ 使用方法就會覺得教不要用是對的
推 : linux kernel用超多11F 10/12 07:56
→ : 我不用goto這種爛指令 我都用comefrom12F 10/12 08:05
推 : 應該要有一本書叫 the art of goto13F 10/12 08:11
→ : 宅氣衝天14F 10/12 08:11
推 : 快推 不然人家會以為我看不懂15F 10/12 08:18
推 : 我認為goto解讀會變差..不太用16F 10/12 08:18
推 : 推17F 10/12 08:29
推 : 不用goto是哪些人...?18F 10/12 08:37
推 : 深入淺出goto19F 10/12 08:39
推 : 113不簡單20F 10/12 08:39
推 : 把exception包成函式不就好了?21F 10/12 08:41
推 : 文組如我…看不懂22F 10/12 08:48
推 : 我們老師跟我說這樣會破壞程式結構叫我們不要使用,就23F 10/12 08:52
→ : 連課本裡也寫不建議使用?
→ : 連課本裡也寫不建議使用?
推 : 推 認真文 goto在err_handling真的方便XD25F 10/12 09:04
推 : 優文推 goto實務好像都拿來做例外的處理26F 10/12 09:14
→ : 因為例外處理本身就是一件破壞程式結構的事情27F 10/12 09:19
推 : 就科技廠的機台可以處理run time error hang up狀況28F 10/12 09:20
推 : 推29F 10/12 09:25
推 : 推30F 10/12 09:32
推 : 推31F 10/12 09:48
推 : 沒有delimited continuation的低階語言才會要用goto32F 10/12 09:51
→ : 動態配製那邊通常會用do{}while(0);加上break;吧33F 10/12 09:52
推 : 不是,通常是最後要回收 memory 或其他 resource34F 10/12 09:54
→ : goo.gl/p3v23T
→ : goo.gl/p3v23T
推 : 快推,不然人家以為我不懂36F 10/12 10:38
推 : 長知識推37F 10/12 10:49
推 : U文38F 10/12 10:51
推 : 我知道goto Hawaii39F 10/12 11:29
推 : 完全看不懂 哀 難怪我只能領低薪40F 10/12 11:30
推 : 我用goto只會把自己搞混 看來是功力不足@@41F 10/12 12:08
推 : 完全看不懂 哀 難怪我只能領低薪42F 10/12 12:22
推 : 樓上我也是43F 10/12 13:06
→ : 問高納德教授啦44F 10/12 13:25
推 : 沒辦法R C++比較強,goto基本上沒用了45F 10/12 13:34
推 : C++ 能比 goto 難懂的東西多得是46F 10/12 14:30
推 : 用do{}while(0)+break,跳出do之後還是要跑過接下來的每一行47F 10/12 15:39
→ : goto可以根據不同的錯誤,跳過某些行。當然也可以在break
→ : 前設好錯誤碼,再根據錯誤碼寫if/else,但這樣反而很亂..
→ : goto可以根據不同的錯誤,跳過某些行。當然也可以在break
→ : 前設好錯誤碼,再根據錯誤碼寫if/else,但這樣反而很亂..
推 : 嗯,同意50F 10/12 15:42
--
※ 看板: Gossiping 文章推薦值: 3 目前人氣: 0 累積人氣: 2029
1樓 時間: 2017-10-13 10:51:22 (台灣)
→
10-13 10:51 TW
沒有人說不能用goto。如果goto不能用,在設計C語言時就不會放進去了。只是說goto用太多會讓人在閱讀code上很不方便。
回列表(←)
分享