gotoを恐れず使う兵共がfinallyや多重breakを語るスレ
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2005/08/11(木) 11:18:150652デフォルトの名無しさん
2008/02/16(土) 12:31:140653デフォルトの名無しさん
2008/02/16(土) 12:35:43(最適化でレジスタに割り当てられると見た目じゃわかんないけど)
goto foo;
{
int bar = 44;
foo:
printf("%d\n", bar);
}
で 44 が表示されるべきだったかどうだったか調べてみる...
0654デフォルトの名無しさん
2008/02/16(土) 12:49:410655デフォルトの名無しさん
2008/02/16(土) 13:40:44同じ関数内のループに飛び込んでるだけだろ
0656デフォルトの名無しさん
2008/02/16(土) 15:39:42普通の実装ならブロックローカルな変数も関数呼び出した時点で
スタックに領域確保するんじゃねーの?
0657デフォルトの名無しさん
2008/02/16(土) 15:51:47gotoは「局所的な制御」にしか使わないから。
そして「構造」は「常に全体が対象」だ。
燃料としては不足だ。
0658デフォルトの名無しさん
2008/02/16(土) 16:03:24> gotoは「局所的な制御」にしか使わないから。
> そして「構造」は「常に全体が対象」だ。
もちろん>>651はそれが前提で書いていると思うが?
全体を見ずに局所だけを見ているからgotoを使いたがる
というのが>>651の趣旨だと思うが。
0660デフォルトの名無しさん
2008/02/16(土) 17:15:16それは言語の設計思想によるんじゃないかな。
goto前提な言語なら自然とgoto使うことになるし、
goto原則使わないのが前提な言語を使っていて、
かつ、全体の構造を考える習慣がついていれば、
gotoが必要っぽい状況になったら自然と全体の
構造を疑う方向に目が向くと思うよ。
0661デフォルトの名無しさん
2008/02/16(土) 17:57:340662デフォルトの名無しさん
2008/02/16(土) 18:21:23gotoを使わないだけの理由で全体の構造を変えることとでは
天と地ほどの差があるけどな。
0663デフォルトの名無しさん
2008/02/16(土) 19:07:13構造を見直したい程gotoが気になるなら、まず
設計に対する姿勢から疑わないと。
0664デフォルトの名無しさん
2008/02/16(土) 19:09:490665デフォルトの名無しさん
2008/02/16(土) 19:13:470666デフォルトの名無しさん
2008/02/16(土) 19:14:420667デフォルトの名無しさん
2008/02/16(土) 19:16:310668デフォルトの名無しさん
2008/02/16(土) 19:17:270669デフォルトの名無しさん
2008/02/16(土) 19:32:20> 初心者向けの指標としては有りだろう。
gotoを使いたがるのは初心者が多いという意味で賛成だ。
0670デフォルトの名無しさん
2008/02/16(土) 19:34:40そんな君の発言「紙一重」wwwwwwwwwwwww
0671デフォルトの名無しさん
2008/02/16(土) 19:39:57かなり苦しいんじゃないの?
0672デフォルトの名無しさん
2008/02/16(土) 19:46:220673665
2008/02/16(土) 19:56:31そういう意味での賛成は遠慮させていただく。
「どうしてもgotoが必要な場面になったら、構造を見直してみよう」
のようなアドバイスは、初心者向けにはいいかもしれない。
終端条件やデータ構造を見直したら、もっといい方法がみつかるかもしれない。
けれど、そのgotoが適切だと思うなら、見直す必要もない。
gotoはあくまでもきっかけとして、である。
クロージャとかlambdaが欲しいな、と思いながらgotoを書く事もある。
goto(と飛び先のラベル)の場所が適切なら、問題ない。
0674665
2008/02/16(土) 19:57:150675デフォルトの名無しさん
2008/02/16(土) 19:58:19全然わかんない。論争根源の論文の
http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF
と同様なネガティヴキャンペーンにしか見えないぞ。
0676デフォルトの名無しさん
2008/02/16(土) 20:00:06他人のgotoまみれコードを保守した経験がない
ビギナーさん
0677デフォルトの名無しさん
2008/02/16(土) 20:06:450678デフォルトの名無しさん
2008/02/16(土) 20:12:360679デフォルトの名無しさん
2008/02/16(土) 20:15:420680デフォルトの名無しさん
2008/02/16(土) 20:15:59gotoつかう人は「goto使ったほうが良い」と判断しているから使うんだけど。
gotoを使わずに簡潔に書けるならば、好き好んで使ったりはしないよ。
0681デフォルトの名無しさん
2008/02/16(土) 20:16:450682デフォルトの名無しさん
2008/02/16(土) 20:20:09> gotoつかう人は「goto使ったほうが良い」と判断しているから使うんだけど。
その判断が狭すぎるという話じゃなかったのか?
0683デフォルトの名無しさん
2008/02/16(土) 20:35:450684デフォルトの名無しさん
2008/02/16(土) 20:43:020685680
2008/02/16(土) 20:48:32ああそうさ。必要も無いのにgoto使うというのはたしかに判断が狭いということだ。
これは開発担当のスキルの不足を反映しているのに過ぎない。
この問題の根源は開発担当に対するスキル管理の不足/欠如だよ。
悪いのはgotoやgotoを使ったプログラムやgoto使った人間では無いことを確認したいわけよ。
だけどgotoの使用判断は開発担当の職掌さ。
どのようなロジックにおいてもgotoを使わないほうが優れているという証明が出来ない限り、
goto禁止ルール自体は不当なルールだと言いたいね。
0687デフォルトの名無しさん
2008/02/16(土) 20:51:54徹底的にgotoを使わなくて済むようにしてほしいね。
多重breakをできるようにしたり、try-catch-finallyにデストラクタを用意したり。
0688デフォルトの名無しさん
2008/02/16(土) 20:53:440689デフォルトの名無しさん
2008/02/16(土) 20:54:14汚いgoto文を見ただけで、「goto禁止」は、まりにも短絡的すぎ。
for〜continue〜break文にせよ、do〜while文にせよ、if文にせよ、try〜catchにせよ、
ネストしまくりでワケワカラン汚いコードを書くヤツは、そこらへんにウヨウヨいる。
いったいどうやったら、構造化言語をここまで汚く書けるのか、もう信じられんほど。
なのになぜ、goto「だけ」がこれほどまでに差別されなければならないのか。
・・・ま、そこらへを書くと、またキチガイが湧くんでホドホドにしとくが。
美しく書けばgotoは害では無い。これは確か。
0690デフォルトの名無しさん
2008/02/16(土) 20:56:25とりあえず、モチツケ。
無条件goto禁止、については合理的な理由の説明は無かったはずだ。
0691デフォルトの名無しさん
2008/02/16(土) 20:56:46goto禁止したところで、そのうち9割くらいはフラグ付きwhileとか結局スパゲティを書く気がするけど。
0692デフォルトの名無しさん
2008/02/16(土) 21:02:41gotoには「最後の手段」の側面もあるからね。
gotoとラベルの置き場所の自由さっぷりは両刃の剣なわけで。
0693デフォルトの名無しさん
2008/02/16(土) 21:04:39なんかもう脳内事例で語ってるようにしか見えないんだが。
0694デフォルトの名無しさん
2008/02/16(土) 21:06:34全然読みづらくない。こういうgotoは全く問題にならないし、
Cで綺麗にエラー処理を書こうとしたらああならざるを得ないと思うけどな。
>>691
人格攻撃は生産的じゃない。もっと実になる議論をしようや。
0695デフォルトの名無しさん
2008/02/16(土) 21:08:160696デフォルトの名無しさん
2008/02/16(土) 21:14:12多重ループからの抜け出し、エラー処理、リソースの開放で定型的に使うならありだろ。
gotoを避けるというのを関数分割のタイミングにするのは馬鹿らしいし。
大体goto使ったが為のスパゲッティコードなんて大昔の非構造化BASIC以来見たことないぞ。
否定派
goto駄目。絶対。goto使う奴はコードが汚く低能!
0697デフォルトの名無しさん
2008/02/16(土) 21:24:220698デフォルトの名無しさん
2008/02/16(土) 21:26:41その程度の扱いを受けて当然だな。
0699デフォルトの名無しさん
2008/02/16(土) 21:28:11gotoを自由奔放に使いまくるという話の間にはずいぶんと開きがあることに
>>693が気付く時は来るのだろうか。。。(遠い目
0700デフォルトの名無しさん
2008/02/16(土) 21:34:550701デフォルトの名無しさん
2008/02/16(土) 21:35:50その程度の扱いを受けて当然だな。
0702デフォルトの名無しさん
2008/02/16(土) 21:37:07ただ現存する用法すべてに盲目的にケチつける奴がいるだけでw
0703デフォルトの名無しさん
2008/02/16(土) 21:39:47つーか、そもそも現存する用法すべてのリスト、このスレに挙がってるのか?
0704デフォルトの名無しさん
2008/02/16(土) 21:46:240705デフォルトの名無しさん
2008/02/16(土) 21:48:28まあ使えばいいんじゃない?
0706デフォルトの名無しさん
2008/02/16(土) 21:50:220707デフォルトの名無しさん
2008/02/16(土) 21:53:43まぁまともな会社で、まともな品質のプログラムがかけるプログラマでも
Linuxのソースクオリティで書けるプログラマなんて少ないけどな。
0708デフォルトの名無しさん
2008/02/16(土) 21:54:10ナイ、ナイ
0709デフォルトの名無しさん
2008/02/16(土) 21:56:40Linuxカーネルの可読性の低さはBSDハッカーの格好の標的だったのに。
今じゃLinuxカーネルが高品質と言われるようになったか。。。(遠い目
0710デフォルトの名無しさん
2008/02/16(土) 21:59:19そう指摘されるといや、そんなことないよとごまかす嫌goto厨。
もう年相応の趣味を持てずただリアルでの孤独を癒す為に宗教論争スレに常駐してるだけみたいだね。
0711デフォルトの名無しさん
2008/02/16(土) 22:00:11Cのマクロで例外処理を実装するような使い方はきれいなsetjmpの使い方だと思う。
0712デフォルトの名無しさん
2008/02/16(土) 22:00:190713デフォルトの名無しさん
2008/02/16(土) 22:01:45なるほど、poor man's continuationね。確かにそうかも。
0714デフォルトの名無しさん
2008/02/16(土) 22:05:480715デフォルトの名無しさん
2008/02/16(土) 22:07:12Cで例外つっても、単にジャンプすればいいだけじゃなくて、それ以外にも
C++でいうデストラクタの処理とか色々必要になるわけで。setjmpはつかわないわ。
0716デフォルトの名無しさん
2008/02/16(土) 22:07:50クオリティの高さに話を逸らしてるお馬鹿さんがいますね
0717デフォルトの名無しさん
2008/02/16(土) 22:26:19無関係だということにしたい人がいますね
0718デフォルトの名無しさん
2008/02/16(土) 22:27:27どうせマクロなんだからfinally実装しちゃえばいいじゃない。
NSAutoreleasePoolみたいに「暇なとき始末してね」と予約しておいて、
早めに開放したい資源(ファイルディスクリプタとか)を利用した後や、
イベントループのように定期的に戻ってくる場所で開放する手もある。
0719デフォルトの名無しさん
2008/02/16(土) 22:33:20そんな難しいことできるわけないだろ
お前実装してみろよ
0720デフォルトの名無しさん
2008/02/16(土) 22:33:493年目くらいで、やっとできるとまわりから認められ、
ちょっと自信が付いてきたやつ。
後輩に教える機会も増えて、得意になって、よく分からんくせに
中途半端な知識でものを語ってるんだろ。
gotoの話なんて、もう十何年も繰り返されてるのに。
0721デフォルトの名無しさん
2008/02/16(土) 22:35:040722デフォルトの名無しさん
2008/02/16(土) 22:37:110723デフォルトの名無しさん
2008/02/16(土) 22:40:58-嫌goto厨の主張はいつも抽象論の域をでない
-抽象論でgotoを否定するだけで、「おえらいさんが言ってただろ?だから従え」
という傲慢な主張しかない
-goto肯定派の具体的な例に関しては、「構造的に考えれば、とか、構造を再度
検討しなおせば」とか、これまた抽象論でしか返さない。
要するに、嫌goto厨の主張なぞその辺の学者のタワゴトにしかすぎず、
なんら実務面の利点を示しているわけではない。
0724デフォルトの名無しさん
2008/02/16(土) 22:41:48こんなコードを書く香具師がgotoを使ったらどんな恐しいことになることか。
0725デフォルトの名無しさん
2008/02/16(土) 22:43:00goto厨の提示したソース、どうにも実務的なのはないのだが。
あるというのならアンカーで示してくれ。
0726デフォルトの名無しさん
2008/02/16(土) 22:46:13-goto厨の主張はいつも抽象論の域をでない
-抽象論でgotoを肯定するだけで、「おえらいさんが言ってただろ?だから従え」
という傲慢な主張しかない
-goto否定派の具体的な例に関しては、「実用的ではない、とか、
gotoでも害がなければ」とか、これまた抽象論でしか返さない。
要するに、goto厨の主張なぞその辺のワナビーのタワゴトにしかすぎず、
なんら実務面の利点を示しているわけではない。
0727デフォルトの名無しさん
2008/02/16(土) 22:48:49ようするに目糞鼻糞
0728デフォルトの名無しさん
2008/02/16(土) 22:50:360729デフォルトの名無しさん
2008/02/16(土) 22:59:31goto使ったらダメとにかくダメって言ういかれぽんちに、
んなわけねーだろって言ってるだけだろ。
0730デフォルトの名無しさん
2008/02/16(土) 23:02:24せいかい^^
0731デフォルトの名無しさん
2008/02/16(土) 23:31:190732デフォルトの名無しさん
2008/02/16(土) 23:35:00だれ?
0733GOTO
2008/02/16(土) 23:56:150734デフォルトの名無しさん
2008/02/17(日) 00:18:430735デフォルトの名無しさん
2008/02/17(日) 03:32:45typedef struct ex_handler_rec_ ex_handler_rec_;
struct ex_handler_rec_ {
ex_handler_rec_ *volatile prev_;
jmp_buf jbuf_;
const char *volatile ex_type_;
void *volatile ex_data_;
};
ex_handler_rec_ *volatile current_handler_ = NULL;
#define EX_ABBREV(x) x
#define TRY { \
ex_handler_rec_ EX_ABBREV(ex_handler_); \
int EX_ABBREV(need_rethrow_) = 0; \
if (0) BREAK_TRY; /* mandate finally clause */ \
EX_ABBREV(ex_handler_).prev_ = current_handler_; \
current_handler_ = &EX_ABBREV(ex_handler_); \
if (setjmp(EX_ABBREV(ex_handler_).jbuf_) == 0) {
#define BREAK_TRY goto EX_ABBREV(break_entry_)
#define RETHROW goto EX_ABBREV(rethrow_entry_)
#define CATCH(extype) \
} else if (!extype || !strcmp(extype, EX_ABBREV(ex_handler_).ex_type_)) { \
void *EX_ABBREV(ex_data) = EX_ABBREV(ex_handler_).ex_data_;
#define CATCH_ALL \
} else if (1) { \
void *EX_ABBREV(ex_data) = EX_ABBREV(ex_handler_).ex_data_;
0736デフォルトの名無しさん
2008/02/17(日) 03:33:37} else { \
if (0) goto EX_ABBREV(rethrow_entry_); /* supress warning */ \
EX_ABBREV(rethrow_entry_): \
EX_ABBREV(need_rethrow_) = 1; \
} \
EX_ABBREV(break_entry_):; \
if (current_handler_ == &EX_ABBREV(ex_handler_)) /* no exception */ \
current_handler_ = EX_ABBREV(ex_handler_).prev_; \
{
#define END_TRY } \
if (EX_ABBREV(need_rethrow_)) \
throw_exception(EX_ABBREV(ex_handler_).ex_type_, EX_ABBREV(ex_handler_).ex_data_); \
}
void throw_exception(const char *ex_type, void *ex_data) {
ex_handler_rec_ *handler = current_handler_;
current_handler_ = handler->prev_;
handler->ex_type_ = ex_type;
handler->ex_data_ = ex_data;
printf("throw_exception %s\n", ex_type);
longjmp(handler->jbuf_, 1);
}
0737デフォルトの名無しさん
2008/02/17(日) 03:40:13TRY {
#undef EX_ABBREV
#define EX_ABBREV(x) a_##x
TRY {
if (cond)
BREAK_TRY;
throw_exception("hoge", cond2 ? "abc" : NULL);
} CATCH("fuga") {
if (a_ex_data) /* throw_exceptionの第二引数はEX_ABBREV(ex_data)に入る */
printf("%s fuga\n", (char *)a_ex_data);
else
RETHROW;
} FINALLY {
printf("inner finally\n");
} END_TRY;
#undef EX_ABBREV
#define EX_ABBREV(x) x
} CATCH("fuga") {
printf("fuga %s\n", ex_data);
} FINALLY {
printf("outer finally\n");
} END_TRY;
0738デフォルトの名無しさん
2008/02/17(日) 03:46:420739デフォルトの名無しさん
2008/02/17(日) 04:21:39grep goto すりゃ見つかるだろ。
0740デフォルトの名無しさん
2008/02/17(日) 04:25:13あと、for,whileなどのループ内では、このマクロは使えないね。
(BREAK_TRY のあと、ループ脱出条件を再度判定してbreak文を実行しなきゃならない:二度手間)
0741デフォルトの名無しさん
2008/02/17(日) 04:47:212chは行数制限があるから実用されているコードを貼るのは無理だね。
アンカーではなくポインタは示すので、あとは自分で調べて。
# apache が実務的なコードでないという奴はいないよな?
$ grep -r -n goto httpd-2.2.8/server
httpd-2.2.8/server/vhost.c:717: goto bad;
httpd-2.2.8/server/vhost.c:747: goto bad;
httpd-2.2.8/server/vhost.c:754: goto bad;
httpd-2.2.8/server/vhost.c:904: goto found;
httpd-2.2.8/server/vhost.c:916: goto found;
httpd-2.2.8/server/mpm/netware/mpm_netware.c:421: goto got_listener;
httpd-2.2.8/server/mpm/winnt/child.c:954: goto shutdown;
httpd-2.2.8/server/mpm/winnt/mpm_winnt.c:871: goto die_now;
httpd-2.2.8/server/mpm/experimental/event/event.c:1140: goto worker_pop;
httpd-2.2.8/server/mpm/worker/worker.c:882: goto worker_pop;
httpd-2.2.8/server/mpm/prefork/prefork.c:614: goto got_fd;
httpd-2.2.8/server/mpm/beos/beos.c:560: goto got_a_black_spot;
httpd-2.2.8/server/mpm/beos/beos.c:562: goto got_fd;
httpd-2.2.8/server/util_xml.c:58: goto read_error;
httpd-2.2.8/server/util_xml.c:79: goto read_error;
httpd-2.2.8/server/util_xml.c:88: goto read_error;
httpd-2.2.8/server/util_xml.c:93: goto parser_error;
0742デフォルトの名無しさん
2008/02/17(日) 06:54:58おいおい、今さら提示しても遅いって。>>723に
> -goto肯定派の具体的な例に関しては、「構造的に考えれば、とか、構造を再度
とか
> なんら実務面の利点を示しているわけではない。
とか書いた時点で、じゃあgotoの実用的かつ正しい使い方というのは
どんな具体例があったんだよって話なんだから。
0743デフォルトの名無しさん
2008/02/17(日) 06:55:01goto否定派曰く「全てのgotoが駄目だという奴などいない」
であれば、肯定派否定派など互いにレッテルを貼っているだけで不毛な言い合いだな。
「どういう場合にgotoを使うのか、使わないのか」という具体的な議論にこそ意味があると思うが。
0744デフォルトの名無しさん
2008/02/17(日) 06:59:38linuxカーネルの話は723よりも前に出ている。
ま、くだらない貶しあいには興味がないので具体例で。
vhost.cの最初の3つはこういう構造。
static void fix_hostname(request_rec *r) {
...
if (rv != APR_SUCCESS || scope_id) { goto bad; }
...
if (r->hostname[0] != '[') {
for (dst = host; *dst; dst++) {
if (apr_islower(*dst)) { ... }
else if (*dst == '.') { ...; goto bad; }
else ...
}
}
...
return;
bad:
...
return;
}
0745デフォルトの名無しさん
2008/02/17(日) 07:03:07gotoを使わずにより良いコードを書ける人は代案をよろしく。
「744のように端折られると詳細がわからないから書けない」という言い訳はなしな。
「本物」のコードへのポインタは>>741にある。必要なら本物を見てくれ。
0746デフォルトの名無しさん
2008/02/17(日) 07:05:30抽象的な言い合いの間は散々吠えておいて、
こういう流れにされると何もいえなくなる人へ。
「お前はgotoを使うな」
0747デフォルトの名無しさん
2008/02/17(日) 07:22:04static void check_hostalias(request_rec *r) {
処理
for (ループ条件) {
処理 // この部分に、条件を満たしたらcontinueというコードがある
if (判定条件) goto found;
処理 // この部分に、条件を満たしたらcontinueというコードがある
if (判定条件) goto found;
}
return;
found:
r->server = s; // この一文のみ
}
これはごく単純なgotoの例。多重ループでも何でもないが、使わない人フラグを立ててbreak?
r->server=s; return;を二箇所に書くという書き方も、二箇所程度ならありかもね。
0748デフォルトの名無しさん
2008/02/17(日) 07:24:39bad:
...
return;
な部分をマクロにしちゃえばgotoなんて使う必要ないんじゃ?
0749デフォルトの名無しさん
2008/02/17(日) 07:27:08for (ループ条件) {
処理
do {
処理
if (条件) goto got_listener;
処理
} while (ループ条件);
continue;
got_listener:
処理
}
0750デフォルトの名無しさん
2008/02/17(日) 07:32:07goto got_listenerが一箇所なら
if (条件) {処理; break;}で済む問題だな。
複数箇所なら処理をstatic関数にすればいい。
そもそも「処理」ってくくれるぐらいまとまってるんだろ?
0751デフォルトの名無しさん
2008/02/17(日) 07:33:27全体の構造うんぬんの話の検証にはならない。
というか、むしろ局所的な制御しか考えてないと
goto慎重派に言われても仕方ないことになるが。
■ このスレッドは過去ログ倉庫に格納されています