プログラミングで一番嫌われている命令って、、、
せーーーーのっ!!!!
ゴートゥーーー!
はい!、goto命令ですね
そんな可哀想なgoto命令についてアレコレ書いてみたいと思います
- goto命令は諸悪の根源だ!と思って毛嫌いしている人
- goto命令を好きで好きで使いまくっている人
◆解決できるかも知れないお悩み
- goto命令の使い方のご提案
Contents
goto命令って悪いのか!?
先に言っておきますが、この記事はgoto命令を擁護します
- こんな風にgoto命令を使ってみてはどう?
- こんな風なgoto命令の使い方はダメだよね?
というような事を書きます
そもそも、goto命令悪人説がありますが、ホントにgoto命令が悪いの!???
そうなの???
違う違う、そうじゃ…そうじゃない!!!
お前の使い方が悪いんじゃーーーーーっ!!!!
goto命令は全く悪くないんじゃーーーーーーっ!!!
使い方の悪さを棚に上げてgoto命令ひとりに責任をなすりつけるなんてプログラマの風上にも置けない!!!
そもそも、なぜgoto命令が悪く言われているのか!?
goto命令が悪く言われるのはそれなりに理由があるのは理解してますよ
実際僕は仕事でgoto命令を使ったこと無いですし(笑)
まぁ、趣味のプログラムでも使ったことないかなwwwwwww
goto命令の何が悪いのか、振り返ってみましょう
と言っても、その理由は一つだけですけど・・・
いつでもどこでも(と言っても同じ関数内だけのはず)飛んで行ける!
このコードを見ると、ちょっとややこしいですよね
※もっとややこしく書きたかったけど、これ以上goto命令使うとワケ分からんようになるので止めました(笑)
#includevoid subFunction(void); main() { int hoge = 10; int fuga = 20; int hege; int i; hege = hoge + fuga; goto JUMP1; hege = 100; JUMP1: printf("JUMP1 %d \n", hege); goto JUMP2; hege = 200; printf("---- \n"); JUMP2: for(i=0; i<100; i++) { printf("JUMP2 %d \n", hege); goto JUMP3; } hege = 300; printf("---- \n"); JUMP3: printf("JUMP3 %d \n", hege); return ; } void subFunction(void) { JUMP3: printf("aaaa"); return; }
>gototest.exe JUMP1 30 JUMP2 30 JUMP3 30
ところどころでhege
に値を入れてるんですけど、結局goto命令のせいで値がセットされないんですよね
printf("---- \n");
も実行されないし
for命令
なんて、100回処理するのかなと思いきや1回しか処理しないし、
そうなんです、gotoを多用すると分かりづらいソースコードになっちゃうんです
今回のサンプルは処理の流れが下に下に行くようにしているので読めなくもないですが、
上に戻ったり、下に行ったり、上に戻ったり、下に行ったり、・・・・
みたいなことをすると、、、もうそのソースコードを読むのは不可能に近くなります。
そら、嫌われますわwww
でもgoto命令の代わりにこんなことやっていませんか?
ちょっとC言語以外ではよく分かりませんが、goto命令を使いたいけど使えない時にこんな書き方しませんか?
オブジェクト指向系であればfinally的なものを使いますよね
#includemain() { int i; for (i=0; i<100; i++) { printf("count %d \n", i); if(i > 3) { break; } } printf("end \n"); return; }
>goto2.exe count 0 count 1 count 2 count 3 count 4 end
#includemain() { int i = 0; while(1) { printf("count %d \n", i); if(i > 3) { break; } i++; } printf("end \n"); return; }
>goto3.exe count 0 count 1 count 2 count 3 count 4 end
#includemain() { int i = 0; char error = 0; char something = 1; do { /* 何かの処理...... */ if(something) { printf("something \n"); /* エラーフラグON */ error = 1; } /* 何かの処理...... */ if(error) { printf("error \n"); /* do を脱出 */ break; } /* 何かの処理...... */ printf("while-end \n"); } while(0); printf("end \n"); return; }
>goto4.exe something error end
別にこういう書き方が悪いとは思いません
が、やってることはgoto命令と大差無いですよね
なので、goto命令だけを悪者にするのはちょっと可愛そうです
それでもワシはgoto命令を擁護するでっっっっ!
まぁでも、前章の書き方は飛び先が固定されるしそれ以外の使い方が無いんですよね
goto命令のように飛び先自由ってこともできないのでgoto命令と全く同じというわけではないですね
finally的な命令が無い場合、この書き方は結構便利だったりします
僕も仕事書いたことありますし
で、提案ですけど、goto命令もfinally的に使ってみてはどうでしょう?
こんな感じ↓
#include#include #include main() { int i = 0; char error = 1; char* pc1 = NULL; char* pc2 = NULL; /* メモリ確保1 */ pc1 = (char*)malloc(10); if(pc1 == NULL) { printf("メモリ1確保失敗 \n"); goto JUMP_CLEANUP; } printf("メモリ1確保成功 \n"); /* 何かの処理...... */ /* メモリ確保2 */ pc2 = (char*)malloc(10); if(pc2 == NULL) { printf("メモリ2確保失敗 \n"); goto JUMP_CLEANUP; } printf("メモリ2確保成功 \n"); /* 何かの処理...... */ if(error) { printf("error \n"); goto JUMP_CLEANUP; } /* 何かの処理...... */ printf("end \n"); JUMP_CLEANUP: if(pc1 != NULL) { printf("メモリ1解放 \n"); free(pc1); } if(pc2 != NULL) { printf("メモリ2解放 \n"); free(pc2); } return; }
>goto5.exe メモリ1確保成功 メモリ2確保成功 error メモリ1解放 メモリ2解放
あくまでも後始末のみに使うんです
コーディング規約でそう決めて、コードレビューでチェックすればいいのでは?
goto命令の飛び先ラベルも固定にしてしまえば、grep(←全てのファイルを一括で検索すること)でチェックできるし
さいごに、
別にgoto命令自体は悪くなくて、人間の使い方が悪いだけなのに....
まぁ、だからと言って使うことは推奨しませんし、僕も今後も使わないと思いますwww
でも、goto命令自体は悪くない!!
悪いのは人間だ!!
それを言いたいだけです...
あと、ハンガリアン記法も本当は悪くないんですよ
誤解されたまま広まってしまい、ハンガリアン記法も悪いヤツという風潮になってしまいました
nb
みなさん、プログラミングの命令や記法にもっと愛情を注いであげてください!!!
アセンブラ「ん? goto使おうがどうしようが、jmp命令使いまくりだぞ!?」
※gccなら、gcc -S hoge.c
かgcc -S -g hoge.c
でコンパイルしてみてね
プログラミング のレッスンに興味がある方、レッスン内容を聞いてみたい方、なんなりとお問い合わせください。
無料体験レッスンもありますのでお気軽にどうぞ!!!