コミュニティアイコン プチコン 非公式コミュニティ トピック

アバター
Na ◆QoELVrBXBQCI
2019/12/4 19:30
質問
DEF(戻り値あり)内のGOSUB
DEF HOGE(A)
GOSUB @1
RETURN 値

@1
RETURN
END

上のプログラムを実行すると、@1へGOSUBした後のRETURNでUninitialized variable usedが発生します。どうしたらGOSUBしたところに戻れますか?
戻り値なしのDEFでは正常動作するようです。

コメント

アバター
☆Tatsukin★ 2019/12/4 20:13 ◆C.1dcTLZggd7
DEF内にGOSUB入れる場合は
GOSUB "0:@1"
みたいにスロットから入れなければならなかったはず(記憶違いだったらすみません)
アバター
Na 2019/12/4 20:16 ◆QoELVrBXBQCI
スロット番号も指定するのはDEF外のラベルにGOSUBする時では?
アバター
say 2019/12/4 20:28 ◆1nbKtD/tFu04
サブルーチンのほうのRETURNにも戻り値を書けばいいようですね
その戻り値自体は特に意味がないみたいです

たぶん、仕様の穴なのかも知れません
アバター
しんいち 2019/12/4 20:28 ◆lHy.hAWXbthn
3号/BIGでは、DEF内のGOSUBは通常、行ったきりになります(GOTOと同様)。戻り値なしのDEFでもエラーにならなかっただけで、期待通りの動作にはなっていないと思います。スロット番号付きのラベル(0:@LABEL等)にすると戻ってくるようですが、ラベルはグローバル(DEF外)じゃないとダメだったと思います。
それでもDEF内でGOSUBみたいなことがしたい場合、例えば下記のようにするとか。
DEF HOGE(A)
VAR R$
R$="@A":GOTO @1:@A
RETURN 値

@1
GOTO R$
END

プチコン4ではDEF内でも普通にGOSUBできるようになってるみたいですね。
アバター
☆Tatsukin★ 2019/12/4 20:28 ◆C.1dcTLZggd7
読解力がなくてすみません。

試しに後ろのRETURNの後にも値を入れてみたらいけました(ただしこの値は反映されない)
アバター
Na 2019/12/4 20:42 ◆QoELVrBXBQCI
>sayさん
確かに戻り値を書いたら動作しました。バグですかね?

>しんいち
戻り値なしのDEFでは、
DEF HOGE
?"A"
GOSUB @1
?"B"
RETURN
@1
?"1"
RETURN
END
HOGEを実行すると
A
1
B
と表示されるので、正常にGOSUBできていると思います。
でもヘルプには確かにDEF内ではGOSUBできないと書いてありますね。
アバター
SatoshiMcCloud 2019/12/4 20:51 ◆Z1qfV11i63Jr
試してないので恐縮ですが、「DEF HOGE(A)」の次の行に「A=1」と入れてみてください
アバター
Na 2019/12/4 21:34 ◆QoELVrBXBQCI
A=1入れても特に何も変わりませんでした
Aに代入してしまったら引数を渡す意味がなくなってしまうのでは?
アバター
しんいち 2019/12/4 22:07 ◆lHy.hAWXbthn
戻り値なしDEF、ちゃんとGOSUBできてるっぽいですね。以前いろいろ試したときはダメだったはずなんだけど、いつの間にか更新されてたのかな。
戻り値ありDEFでも、sayさん、☆Tatsukin★さんのおっしゃるようにGOSUBのRETURNにもダミーで値を書いとけば、ちゃんと動いてるっぽい。

但し、今回の単純なケースだけたまたま上手く行ってるだけかも、という心配はある。
アバター
say 2019/12/4 22:39 ◆1nbKtD/tFu04
>ヘルプには確かにDEF内ではGOSUBできないと
普通に使う場合では普通に使える感じですが、変に使う場合は挙動がおかしく(流れが把握しにくく)なるので、
それだったら、元から「できない」と注意してるのかも知れませんね
アバター
Na 2019/12/4 23:09 ◆QoELVrBXBQCI
>sayさん
だったらいつでも使える仕様か全く使えない仕様のどちらかにすればいいのにと思ってしまいます
アバター
say 2019/12/5 2:05 ◆1nbKtD/tFu04
プライベートなサブルーチンだと思うと、全く使えないってーのも惜しい様な感じがします
「行ったら帰る」という普通の使い方さえしてれば、特に問題ないんですし
「行きっぱなし」だと、かなり悩まされます ←これが先の「変な使い方」

ちなみに、変な使い方の具体例なんですが
1:VAR A
2:FOO
3:DEF FOO
4: GOSUB @1
5: @1
6: A=A+1
7:END
こんな感じ
一見、GOSUB @1のスタックを残したまんま、FOOから抜ける様に見えますが、実際はGOSUB @1のスタックを消費してからFOOを抜けます
☆どうやらDEFのENDはRETURNの意味合いがあるみたいです

流れは以下の通り
1→2(→3→4→5→6→7※→5→6→7)
※ここでのENDはGOSUB @1のRETURNとして機能し、4行目の次に戻る
6行目を2回通るので、A=2になる
アバター
Na 2019/12/5 18:50 ◆QoELVrBXBQCI
はぁーなるほど...
確かにそれはややこしいですね
アバター
ツララ 2019/12/6 13:34 ◆ArUdBYOYME1V
そもそもDEFの中にサブルーチンを置く様なプログラムだと、設計から見直した方がいいのでは?
DEFのメリットって使う変数をローカル扱い出来て、使ったメモリも処理終了時に自動解放されることですし。
メインルーチン>サブルーチン>DEF
みたいな構成がベストかと。

表題の処理ってつまりこういうことでしょう?
DEF HOGE1(A)
 RETURN HOGE2()
END
DEF HOGE2()
 RETURN 値
END
アバター
Na 2019/12/6 17:06 ◆QoELVrBXBQCI
>ツララさん
その例でいうなら、HOGE1のローカル変数はHOGE1の外では使いたくないが、HOGE2の中でHOGE1のローカル変数を使いたい、という状況です。
アバター
say 2019/12/6 19:56 ◆1nbKtD/tFu04
スコープも知らないのに、よく「設計から見直し」なんて言えるもんだ
スコープを知ってりゃ、そんな駄コード出せるワケがない
それにGOSUBの返り値?をHOGEの返り値にするとはどこにも書いてない

「設計から見直し」した場合、少なくともこうなる
DEF HOGE(A)
 FOO 使う変数 OUT 変化する変数
 RETURN 値
END
DEF FOO 使う変数 OUT 変化する変数
 処理
END

コメントを書く

  • こちらは「プチコン3号」「プチコンBIG」など、プチコンシリーズに関する話題を扱ったコミュニティです
  • プチコンシリーズにまったく関係ない書き込みはご遠慮下さい。削除の対象となります
  • こちらにはその他のゲームや雑談のコミュニティはなく、作る予定もありません (ひとりで管理できないため)。ごめんなさい
  • ユーザー登録なしで書き込みができます
  • 秘密の合い言葉は成りすましの防止 (トリップ機能)、書き込みの編集時の本人認証に使用します
  • 秘密の合い言葉に他人に推測されやすい言葉、他サービスと同じパスワードは入力しないでください。
  • 書き込むと、投稿時に入力したお名前と秘密の暗号が記憶され、ログイン状態になります

- WEB PATIO -