@IT情報マネジメント会議室は、2009年4月15日に新システムに移行しました。
新たに書き込みを行う場合には、新しい会議室をご利用ください。
- PR -

なぜ「GOTO文」を使っては、いけないのですか?

投稿者投稿内容
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2004-04-26 13:38
るぱんです。
引用:

はにまるさんの書き込み (2004-04-26 10:26) より:
引用:

m.kuさんの書き込み (2004-04-25 19:28) より:
> 「そうだよね、セーフだよね。」と思われた方、
> なぜ、On Error Goto はセーフなんですか?

別にGOTO自体は悪いとは思ってない(使い方の問題)ですが、
これに関しては「制御の自由度が低いし使われ方がお決まりの方法」なので
プログラムの制御が書き手の支配化から逸脱することが少ないからでしょう。

ただのGOTOだと無節操に使うと、書き手の支配下から逸脱した動作を
簡単に起こしやすくなりますが、これは概ねパターン化してますから。


ご返答ありがとうございます。

私が、るぱんさんの返答をスルーしてしまった理由は、
m.kuさんが述べられている、「使われ方がお決まりの方法」にあります。

<<中略>>

これは「1.パターン化されている」、「2.ルーチン外に出る事は無い。」の2つがあり
私は一番大きな点は、「2.ルーチン外に出る事は無い。」としました。

これ実は、Goto も IF Gotoも一緒です。
他の言語でも、ルーチンやメソッドを超えるジャンプ命令は無理では無いでしょうか?

結局、GOTO文は、この「ルーチン外へ飛ぶ事は出来ない」制約により
現在のプログラム構造で使う場所とは限られてくると思います。
話を聞く限り、ループ系処理に集中していますね。

GOTO文が及ぼす、悪例のプログラム構成を「スパゲティ」に例えますが、
これは、ルーチン構成等の処理分割で大半が解決されると考えます。

後は、ルーチン内の問題ですが、ここで「GOTO文」を問題とする場合、
もしかすると、既存のGOTO文の問題とは別物かもしれません。
# ってそこまで答えが出なかった。



>m.ku様

逆に何故ダメかお伺いしてみたいです。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-04-26 14:02
はにまるです。
引用:

るぱんさんの書き込み (2004-04-26 13:38) より:
>m.ku様
逆に何故ダメかお伺いしてみたいです。


るぱんさんからm.kuさん宛ての投稿ですが、
ただ、私からしてm.kuさんの投稿に「ダメ」と
思わせる文書が見当たらないのですが?

如何でしょう?るぱんさん
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2004-04-26 14:10
>はにまる様

何故セーフなんでしょう?
    ↑↓
何故アウトなんでしょう?

二つ一組でメリットとデメリットがわかるからです。
m.kuさん宛にしたのは、
理解しての発言かどうかか知りたかったからです。

1.(わからないんだけど)「何故セーフなんでしょう?」と言うのと、
2.(わかってるんだけど)「何故セーフなんでしょう?」と言うのが違うと考えてまして、

どういうお立場での発言か気になったからです。

前者(1のケース)はその後全員にお尋ねしてみたいです。
後者(2のケース)では何故かお伺いしてみたいのです。
コブラ
ぬし
会議室デビュー日: 2003/07/18
投稿数: 1038
お住まい・勤務地: 神奈川
投稿日時: 2004-04-26 14:13
setjump(), longjump() はCの言語体系で正式に使用が認められている。
Cで goto を使うには一つの関数内でなければならないが、longjump() はこれより酷い振る舞い
をする。

つまり、 goto の使用を非難するならば、 longjump() はそれ以上に非難されなければ
ならない。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-04-26 14:45
引用:

コブラさんの書き込み (2004-04-26 14:13) より:
setjump(), longjump() はCの言語体系で正式に使用が認められている。
Cで goto を使うには一つの関数内でなければならないが、longjump() はこれより酷い振る舞いをする。
つまり、 goto の使用を非難するならば、 longjump() はそれ以上に非難されなければ
ならない。


前投稿にもlongjump とあって、何の事か解りませんでしたが、C言語の関数なんですね。

setjump()で戻り箇所を設定して、longjump()で先程設定したsetjump()へ戻る。
この際、サブルーチンの壁を超えて一気に戻れる。

うぉ!すげ〜と思いましたが、利用方法が想像出来ませんでした。

やはり制御系で多用するジャンプ命令なのでしょうか?
OS割込時やエラー発生時に処理を戻して待機させるとか、そんなんですか?
コブラ
ぬし
会議室デビュー日: 2003/07/18
投稿数: 1038
お住まい・勤務地: 神奈川
投稿日時: 2004-04-26 16:43
私程度の者が setjump()/longjump() を使えば、即刻 "Segmentation Fault" とか
"Memory Violation" とか出るのは目に見えてるので、この goto より格段に危険な関数を
使わざるを得ない状況に陥るような仕事は、今までのところありませんでした。

 しかし、goto を非難する者は longjump() も当然非難するでしょうし、 longjump()を
否定する者は、 try ? catch ? throw を否定しなければならなくなるでしょう。

私的には、これはマルチタスク・カーネルでのプロセス・コンテキスト切り替え、スレッド切り替え
に必須なのではないかと思っていますが。unix では プロセス毎にスタック、p-region、 u-area
テキスト、BSS, プログラム、データ領域のアドレス、ファイルディスクリプタを保持しており、
タイムスライス、、OS/2では MAX_WAIT とか定義されとるようですが、、あぁ今どき OS/2 なんか
誰も使わんわな・・・で、ミリ秒単位で時限爆弾があって、こいつらその都度全部一旦待避させる
必要があると思います。カーネルがスーパークラスとしたら、ユーザープロセスは全てサブクラス。
LRUなりラウンドロビンなりの規則に従って、次の「実行状態」になれるプロセスが決定される。

次、どのプロセスが実行されるか、どのサブクラスを使うか、決まり切っとれば飛ぶ必要なんか
なくて、getenv() と & でアドレス決め打ちでハードコーディングすれば良い。構造化大いに結構。
あ、しかし getenv() やと現在の環境を取り出すだけで、コンテキスト切り替わった後じゃ
getenv() しても意味ないか・・・

しかし、カーネルは時間軸で優先度を決定するので、次どのプロセスに切り替わるかは、その時に
なってみないと判らない。だからその時、決定していない飛び先に飛ぶ前に直前の情報をsetjump()で残しておかなければならない。MS-DOS でやった push/pop と同じレベルで論じて良いのかどうか
はともかく、そんな感じかと。

子プロセスに飛んだら、実行状態になって TIME_QUANTUM を使い切った後、再スケジュール
の為に必ずカーネルに割り込まれる。この時、longjump() 復帰したりするのではないかと勝手に
思とる訳ですが。

 後、SMP環境でも、こういう機能は必要になってくるんやないかと思てます。
4CPUで、これまた時間軸で「どのCPU」使うかをスケジューリングする場合、ずっと同じ
CPUに同じプロセス占有させる訳にはいきませんから、やはり、あるミリ秒単位でCPUの切り
替えをしなければならない、と。
そうすると、やっぱりCPUの全レジスタの内容を一時的に待避させる必要があるかと。
これ、setjump/longjump 使うかどうかわかりませんけど・・・

まぁ、私自身も「ぼやっと」しか理解できとらん訳ですが。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2004-04-26 16:53
unibon です。こんにちわ。

setjmp/longjmp などの複雑なものは、いまだかつて使ったことはないのですが、これって言語仕様というよりも API ですよね。これらを問題にするとすれば、他にも似たような API である fork 等をどうするか、といった話もしなければならなくなるような気がします。
#するな、などという意図ではぜんぜんありませんので。
はにまる
ぬし
会議室デビュー日: 2003/12/19
投稿数: 969
お住まい・勤務地: 誤字脱字の国
投稿日時: 2004-04-26 17:47
素人妄想をすると。

setjmp/longjmp って データベース で言うロールバッグ機能と同意義では無いでしょうか?
setjmpでは、環境情報を退避し、longjmpで退避した環境情報を戻し且つ、setjmpに戻ると
あります。

「環境情報」っていうのが何を示すか解りませんでしたが、
これが、プロセス内の変数及びオープン状態ストリームであれば、
正しくロールバッグ機能だな!と思いました。

で、「setjmp」→トランザクション開始、「longjmp」=「ロールバッグ」とすれば、
確かにソース上では、GOTO文の逆戻と一緒に見えますが、処理フロー上は別物と考えます。

 GOTO文は、次の処理を示す。
 longjmp関数は、処理状態を元に戻す。

ん〜、バッチ系処理では「setjmp/longjmp」は、欲しいな..欲しいな..欲しいな..

スキルアップ/キャリアアップ(JOB@IT)