トップページ⇒tech
98コメント25KB

つ、つい Goto文を

■ このスレッドは過去ログ倉庫に格納されています
0001下っ端PGNGNG
使ってしまった。
楽な時あるしね。
0002デフォルトの名無しさんNGNG
goto B;A:
goto C;B:
goto D:C:
goto B:D:
goto A:C:

書いてて自分でわからなくなった。
0003デフォルトの名無しさんNGNG
gotoが許される(かもしれない)不思議な呪文

「だからさあ、Cにタグ付きブロックとunwind-protectがないのが
いけねえわけよ。言語仕様に不備があるんだからしょうがないでしょ」

使ってどうなるかは責任持ちません。
0004デフォルトの名無しさんNGNG
>>3
なんかよくわからないですけど
goto label;
...
{
label:
...
...
}
こんなの?
0005デフォルトの名無しさんNGNG
CommonLispだと、

(block tag
 (foo)
 (return-from tag)
 (bar))

ってな感じ(用語とかは間違ってるかも)で指定したブロックから抜けられるの。
Cのbreakと違ってtagを指定できるから、
ブロックが入れ子になってても抜けたいブロックから抜けられる。

unwind-protectは__try/__finallyといっしょ。
0006デフォルトの名無しさんNGNG
少なくても 関数内関数が無いのはツライな
funcA()
{
 infunc(){・・・};

・・・
infunc();
}
0007デフォルトの名無しさんNGNG
C++なら...
funcA()
{
 struct in{
  static void func(){・・・};
 };
 ・・・
 in::func();
}
00084NGNG
>>5
なるほど。
じゃあ逆にブロックへ入っていくことは出来るんですか?

(goto-block tag)
(hoge)
(block tag (foo) (bar))

とか。。。。。よく考えれば、この機能はいらないですね。。。
0009デフォルトの名無しさんNGNG
goto 真希
0010デフォルトの名無しさんNGNG
goto 理沙
0011デフォルトの名無しさんNGNG
「goto 札だよ」
「goto 札? 幻のニセ札といわれたアレか」
0012デフォルトの名無しさんNGNG
つ、つい ごとう ふみチャンを ... やっちゃいました。ハァハァ
0013デフォルトの名無しさんNGNG
GOTOええ感じ。
0014デフォルトの名無しさんNGNG
GOTO散かぜ薬
0015デフォルトの名無しさんNGNG
C++のコンストラクタで、途中で呼び出し元に返りたい場合って、
return;使えないから、最後に、End:とかいうラベル作るしか方法なくない?

それとも例外を投げるべきでしょうか?
0016>15NGNG
なんで使えないの?
0017>15NGNG
使えるだろ、普通に。
0018デフォルトの名無しさんNGNG
>>7
これ、なんか目ウロコな感じなんだけど、どう?
0019デフォルトの名無しさんNGNG
goto 1
002018NGNG
あ、C++での関数内関数の書き方って点で、gotoとは関係なかった。
この場合だと関数内関数から外側の関数の変数は見えないんだよね。
目ウロコでも無かったか。
0021デフォルトの名無しさんNGNG
goto 勉
0022デフォルトの名無しさんNGNG
gotoハンド
0023デフォルトの名無しさんNGNG
Oh my GOTO!
0024デフォルトの名無しさんNGNG
goto ネーちゃん /*和田アキ子*/
0025デフォルトの名無しさんNGNG
goto >>1;
0026震度3NGNG
gotogotogotogotogotogotogoto
0027デフォルトの名無しさんNGNG
gotoを待ちながら
0028デフォルトの名無しさんNGNG
27のネタ大好き
ちなみにBASIC以外では使ったことがありません
あっそういえば何かの間違いでCに紛れ込ませたことがあったような気も…
0029デフォルトの名無しさんNGNG
Fortranでなら結構使うよ。
0030goto 禁止令!NGNG
PM「とりあえず禁止。」
0031デフォルトの名無しさんNGNG
longjumpつかうよか分かりやすいって。
0032デフォルトの名無しさんNGNG
return と break を不当に乱用するくらいなら goto 使っても問題なし!
0033デフォルトの名無しさんNGNG
goto嫌うのは理屈ばかりのダメPG
0034デフォルトの名無しさんNGNG
つーかここ数年実際に必要になったことないんですけど。
(例外は便利だな)
0035デフォルトの名無しさんNGNG
俺は佐藤。
0036デフォルトの名無しさんNGNG
五頭さんはにんげんじゃないんだ!
0037デフォルトの名無しさんNGNG
>>goto嫌うのは理屈ばかりのダメPG
バカだね
簡単にgotoなしで書けるのに、わざわざgotoを書く馬鹿をどうかしてくれ
ま そいつはgotoつかわないとプログラムかけないみたいだけど
はやく辞めてほしいね
0038デフォルトの名無しさんNGNG
breakにnestレベルが指定できればいいのにね。

{ block top;
  while () {
    if ()
      break; // 普通のbreak
   while () {
    if ()
      break top; //nest break
    if ()
      break; // 普通のbreak
   }
  }
}
この例はあんまり良くないけど。
0039デフォルトの名無しさんNGNG
Perlマンセー!
TOP:{
  while () {
    if ()
      last; // 普通のbreak
   while () {
    if ()
      last top; //nest break
    if ()
      last; // 普通のbreak
   }
  }
}
0040デフォルトの名無しさんNGNG
breakより強力なcrush!
0041デフォルトの名無しさんNGNG
インストーラーやウィザードみたいに
A->B->C->・・・
って言うパターンでおのおのの状態で「戻る」をサポートしたいとき
goto使うのが最も簡潔にかけるし、バグも少ないと思う。
0042デフォルトの名無しさんNGNG
>>41
それはモジュールの分割がきちんとできていないだけ
0043デフォルトの名無しさんNGNG
関係ないけどperl2cってあるの?
0044デフォルトの名無しさんNGNG
>>42
モジュールがどうして関係あるのだ?
004542NGNG
>>44(=41かな?)
ん?A,B,C…をそれぞれのモジュールに分割しておき
あとは、それを状態遷移の形に書けば最も簡潔かと思いますが…
もしかして、私が何か勘違いしている?
0046デフォルトの名無しさんNGNG
>>18
おれもGOTOより 7の方がきになる。
004741NGNG
まず最初に一般的にABCの間で共有しなくちゃいけない情報はかなり
多いはずです。Aでディレクトリ指定してBでなんとかとか。
完全にABCを分割してしまうとこの情報のやり取りが大変になります。

次に上から下に流れ1つ戻るをサポートするだけの簡潔なものになぜ
状態遷移を使ってわかりずらくしなくてはならないのか。というのが
第2点。

それに付随して私は状態遷移を簡潔に表現できるプログラミングテク
ニックを知りません。(GOTOを使うのに比べて)

A:
 if (showDialogA() == CANCEL){
  return;
 }
B:
 if (showDialogB() == BACK){
  goto A;
 }
C:
 if (showDialogC() == BACK){
  goto B;
 }

これより簡潔に書く方法があるのですか?
0048>47NGNG
そんなコードメンテなんてしたくねーぞ。
state = A;
for (;state != END;) {
  switch (state) {
  case A:
   if (showDialogA() == CANCEL) state = END;
   break;
  case B:
   if (showDialogB() == BACK) state = A;
   break;
  case C:
   if (showDialogC() == BACK) state = B;
   break;
  }
}
return;
004947NGNG
>>48
俺はそっちのほうがメンテしたくない。
47なら A->B->C と流れることは自明だが(言語が上から下に流れ
ることを保証してくれているので)
48はその情報が失われている。

なんで47をメンテしたくないのか理由があるのなら聞かせて欲しい。
005047NGNG
ってゆうか48はバグだね。
こういうバグが生まれやすいって言う非常にわかりやすい例をありがとう
0051デフォルトの名無しさんNGNG
>>49
一本道のウィザードで、各ダイアログの処理が単純ならともかく、ちょっと
複雑になると破綻するのが目に見えてる。それだと分岐が発生した時点で、
見通しが極度に悪くなるし、変数スコープが必然的に広くなってしまうのも
バグの温床になる。
0052デフォルトの名無しさんNGNG
一本道じゃないウィザードとか、インストーラーは見たことない。
で、そういう場合の話なのだが。
それにダイアログの処理がどんなに複雑でも関係ないと思うぞ。
それこそ適切にモジュールを分ければすむ話だ。

変数スコープはよくわからん。なぜ必然的に広くなるんだ?

005342NGNG
>>47
 共有する必要がある変数は構造体1つにまとめ、
そのポインタを受け渡しする手段をとります。
 あと、状態遷移で処理させるときには>>48のような方法ではなく
関数へのポインタの配列の方が幸せになれるかと。
ただ次状態への移管がそのモジュールに含められるのならばですが。
 それと47のコードの場合、たとえば仕様変更でBの入力内容
によってC1,C2、C3の処理に分かれる場合、または、
Cの処理を行わずに次状態のDに行く場合工数が高くつきませんか?
48がメンテしたくない理由ってのはこの辺にあると思いますが…
#最初で手を抜くと、あとあと血を見るのがこの業界ですから…
0054厨房NGNG
>>48さんのプログラムは、力一杯Windows用ですよね。
少なくとも、Windowsの場合、処理したらメッセージループを
戻さなければならないから。
47>>さんの方は、普通の、 DOS UNIX のプログラムになるのかな。

実質、求めているものが違うと思う。

005547NGNG
>>53
さっきも書いたけど、一本道って言うのは前提ね。
CをやらずにDに行くのは問題ない。単にCをやらなければいい。

たとえばBはインストールパスを必要としてCがミニマムインストールか
どうかの情報を必要とするとする。
構造体にパックすると言うのはCにインストールのパスを渡すと言うことで
モジュール化の原則からいえばよろしくないと思うぞ。

>>54
思いっきりWindowsで(少なくともMFCなら)動くぞ。
005648NGNG
あ、ほんとだ。おかしいじゃん。わるかったな>47
直すんなら最初の文を nextstate = state = A;に変更
各state = {END,A,B};の所をnextstate = {END,A,B};に変えて
switch文の次に↓の文でも置いてくれや
if (state == nextstate) { /* 状態変化なし */
 switch (state) {
 case A:state = B; break;
 case B:state = C; break;
 case C:state = END; break;
 }
 nextstate = state;
} else {
 state = nextstate;
}
0057厨房NGNG
>>47
メッセージループに戻ってこないじゃん。
0058厨房NGNG
すまね〜、for使っていたんね。
WM_TIMER とかで、処理の分岐で使う手だと思ったから。

鬱だ死のう。
0059デフォルトの名無しさんNGNG
>>53
それは教えたらだめです
情報系の大学いくか
講習会で高いかね払わないと教えてもらえません
006047NGNG
>>56
もちろん状態遷移使ったって実装できる。でも47のほうが簡潔だろ?
0061デフォルトの名無しさんNGNG
47
プログラムの発想がまったく違ってるだけですよ

while(showDialogA() != CANCEL){
  while(showDialogB() != BACK){
   while(showDialogC() != BACK){ }
 }
}
0062デフォルトの名無しさんNGNG
まぁ47氏のように、GOTOを使うスタイルで問題を感じていないんだったら、
別にいいんじゃないの?
刑事バーンに貼れるくらいのコード規模ならGOTOのほうが簡潔に見える
だろうしね。

当方ゲームプログラマで遷移は複雑だし、各状態で書く量も多いし、仕様変更も
多いので、gotoだけで押し通すのは難しいです。

GOTOで押し通せる規模より大きくなってきたときは、さっさと状態遷移に書き直す
(リファクタリングする)。それまではGOTOでラクをする、で良いのでは?
0063デフォルトの名無しさんNGNG
gotoを使いまくる有名人プログラマー
1. djb
2. knuth
あとだれかいる?
0064デフォルトの名無しさんNGNG
その状況でgoto使うなよな…。
せめてcallしろっていうか。
>刑事バーンに貼れるくらいのコード規模ならGOTOのほうが簡潔に見える
んだんだ。それだけのことだ。
ウィザードの仕様が変わるのでGOTOの飛び先直してね!なんてな
話になった暁には、俺なら泣くよ。

>流れることは自明

そういう「局所的な自明」に依存するコーディングは
避ける癖つけようね。そういう部分は「簡単に直せる」んだから。
しわよせ(?)は直しにくいところより直しやすいところに置くべし。
HotSpotって奴か。

>47>>さんの方は、普通の、 DOS UNIX のプログラムになるのかな。

俺、UNIXでも書いているが、そんなコード嫌だよ。

うーん。
今回の例だとStateパターンかなんか使うほうが
メンテ性上がるんでねーか?
state=hogehogeって書くやりかたは、
Stateパターンの御先祖様という意味で、賛成。
006547NGNG
>>64
ウィザードとかインストーラー作ったことある?
基本的に上から下。戻るをサポートとっていうのは変わらんと思うん
だけど。

>ウィザードの仕様が変わるのでGOTOの飛び先直してね!
状態遷移使おうが同じだろ?
「ウィザードの仕様が変わるのでSTATE先直してね!」
状態遷移ってのはGOTOと同じくらいバグの元だぞ。
61みたくするのがGOTO反対派の主流であるべきだ。

で>>61
それが見やすいってなら異論はないが俺は47のほうがわかりやすい。
特にステップが10個くらいになると特にね。
006661NGNG
たしかに
61では上から下へ流れていくイメージはちょっとでませんね
状態遷移を使うのが基本ですがこれは有料です。
というのは冗談ですが
状態遷移は、きちんと設計しないとバグのもとです。
きちんとした、状態遷移というのがなかなか作れないのですが
できるようになると、かなり修正の楽なプログラムになるです。

今日できることは今日のうちにやれ
帰納できることは帰納でやれ
状態遷移でできることは、状態遷移でやれ
とかいうことわざなかったかな。

0067無責任な名無しさんNGNG
>>59
つまり専門には47方式が適当ってこと?
0068デフォルトの名無しさんNGNG
47とは仕事したくないな…
0069デフォルトの名無しさんNGNG
age
0070デフォルトの名無しさんNGNG
for(i=0;i<N;i++){
 for(j=0;j<N;j++){
  for(k=0;k<N;k++){
   for(l=0;l<N;l++){
    for(m=0;m<N;m++){
     if(flag){goto esc;}
     ...
    }
    ...
   }
   ...
  }
  ...
 }
 ...
}
esc:
...

こういうときいちいちbreakで戻るのって信じられないんですが。
0071デフォルトの名無しさんNGNG
はげしくがいしゅつです>70
0072デフォルトの名無しさんNGNG
69はage荒らしです>70
0073名無しの名無しさんNGNG
シベリア送りですな。
0074デフォルトの名無しさんNGNG
>>70
それは、設計自体が間違っているかと思われ…
0075デフォルトの名無しさんNGNG
うむ。そもそもこないなコード書きまへんがな。
0076デフォルトの名無しさんNGNG
gotoをそのまま使うのと他の高級な制御構造を使うのとじゃ意味が異なる。
throwしたまえよ。
(catch 'いやん
[(((((((((((((((((((throw 'いやん 'ばかん))]
)
=>ばかん
0077デフォルトの名無しさんNGNG
JMP命令なしのコードを書いてみよ。
0078デフォルトの名無しさんNGNG
なんのはなしだ>77
0079デフォルトの名無しさんNGNG
GOTO使うなってのは、あとあといろいろわかりにくくなり
やすいからでそ。どんな変な流れでも作れちゃうから。

で、GOTOを使わないと作りにくいような流れは設計が適切でない
可能性がある、とまずは考えるのが普通。
例外時のcleanup処理とか一部確かに有効な時もあるけど。
0080デフォルトの名無しさんNGNG
アゲンナボケ>79
0081名無しおやぢNGNG

銀行GOTO

・・・寒過ぎ・・・。 (-_-;

卯津田士農・・・。
0082デフォルトの名無しさんNGNG
藁>>77アセンブラじゃ無理だわな。
0083デフォルトの名無しさんNGNG
ret or iretで飛ぶのはNGですか
0084デフォルトの名無しさんNGNG
構造化マクロでjmpをソースから追い出すのはNGですか
0085やらないよ。NGNG
>>83スタックに飛び先アドレスPUSHしてか?
RETとIRETの違いがわかるか?ぼうや。
0086デフォルトの名無しさんNGNG
>>81
寒いのは構わないが、ageるんじゃない。
0087デフォルトの名無しさんNGNG
あげ
0088デフォルトの名無しさんNGNG
せっかくさがってたのに・・
0089デフォルトの名無しさんNGNG
何でそんない下げたいの?
#あおりじゃなくてほんとに興味あり
0090地盤賃かNGNG
そのわりにはさがってるな。
0091デフォルトの名無しさんNGNG
GOTOの要不要ってのは究極的にはスタイルの問題になっちゃうじゃん。
どれが正しいってのはありえないから宗教論争になる。
これ以上議論してても堂々めぐりになるだけだよ。

C言語の括弧の位置はどこにする?って話題みたいに……
0092デフォルトの名無しさんNGNG
>>77は、何で書こうと最終的には
cmpとjmp(if文とgoto文)だけに
なってしまうんだよプログラムてのは、
ということを逝っているの?
0093デフォルトの名無しさんNGNG
なんかGOTOって不当に差別されてないかな。C/C++の場合は関数内でしか
ジャンプできないんだから、そんなに危険はないと思う。
でも世の中にはGOTOアレルギーの人がいて一回でも使うとうるさく騒ぎ立
てるから、実際に使うことはないんだけど。
0094さらし信者NGNG
最適化されにくくなるとか?
0095デフォルトの名無しさんNGNG
goto ours;
0096つまんないNGNG
sage
0097デフォルトの名無しさんNGNG
goto sage;
0098デフォルトの名無しさんNGNG
age();
■ このスレッドは過去ログ倉庫に格納されています