5830 FOR I.11=1 TO SP-1
5840 IF SP$(I.11)<>"" AND LEFT$(EN$,LEN(SP$(I.11)))=SP$(I.11) THEN RETURN *NEX
ELSE NEXT I.11
ある経理プログラムの中で、絶対にそこからはジャンプしない場所からジャンプし、エンドレスのルーチンに入ってしまった。いろいろテストした結果、上記のような記述に対してバグがあり、誤作動することが分かった。
もし I.11=1 のときに、たまたまた SP$(I.11)<>"" AND LEFT$(EN$,LEN(SP$(I.11)))=SP$(I.11) であれば、初めから RETURN *NEX をするため、続く
ELSE NEXT I.11を認識しないのである。?
その結果、次に出てきたどこかの NEXT を、
5830 FOR I.11=1 TO SP-1
の受けの NEXT と判断したための誤動作である。

この推定を基に、次のテスト・プログラムを組んでみた。
5000 cls: W$="ABCDEFG": STF$(1)="BCD"
5010 FOR N=1 TO 2: IF INSTR(W$,STF$(N))<>0 THEN STF=1: ELSE print n; "//////////":
NEXT N
5020 print n
5030 FOR A=1 TO 2
5040 print A*10; "-------------"
5050
NEXT
5060
NEXT
( 5070 NEXT )
5100 end
結果は、もし私が推測したようなN88互換BASIC のバグが原因なら、
5010行の
NEXT Nが認識されないため、5010行 FOR N=の受けとして、5060
NEXTが働き、
1
10-------------
20-------------
本来ならこのように表示後、5060行でエラーになるハズ。5060
NEXTに対応する FORが無かったため(DOSなら NEXT With out FORというメッセージ)。
しかし、( 5070 NEXT )を記述しなければ、
1
10-------------
20-------------
2
10-------------
20-------------
このように表示後、正常に終了してしまう。
5070 NEXT も記述すれば、上記と同じ表示後に 5070行で FORが無かったためのエラーになる。
残念ながら互換BASICのバグである。
◇解決策
5830 FOR I.11=1 TO SP-1
5840 IF SP$(I.11)<>"" AND LEFT$(EN$,LEN(SP$(I.11)))=SP$(I.11) THEN RETURN *NEX
ELSE NEXT I.11
や、
5765 FOR N=1 TO ST.ED: IF INSTR(W$,STF$(N))<>0 THEN STF=1:
ELSE NEXT N
のように
THEN ELSE NEXTのように1行の中にまとめずに、次のように分けること。
5830 FOR I.11=1 TO SP-1
5840 IF SP$(I.11)<>"" AND LEFT$(EN$,LEN(SP$(I.11)))=SP$(I.11) THEN RETURN *NEX
5850 NEXT I.11

5765 FOR N=1 TO ST.ED: IF INSTR(W$,STF$(N))<>0 THEN STF=1
7670
ELSE NEXT N
◇欠点としては、かすかに、または少し遅くなるが、仕方ない!
仮に上の例でST.ED=1,000とすれば、 N=1 で終わる場合でも、改善後のプログラムでは必ず N=1,000 まで繰り返されるという差が生まれる。もしこのサブルーチンに何回も入るとすれば、その差は大になるが、正しい結果を得られるためには仕方のないことである。
また、さらにこの誤動作を減らすためには、FOR N=などに対して、受けのNEXTも NEXT Nなどのように変数を付けておくことが大切。変数を省略すれば、誤動作の確率が高まってしまう。
Top 88Menu