|
|
2016/6/24(Fri) 16:06:53|NO.75966
モジュール変数を使ってコーディングしていると特定の状況で何故か varuse が使えなくなるという不思議な現象に遭いました。
delmod が効くのに varuse が効かない状態です。為す術がありません。
以下に確認用のコードを示します。
#module A x
#modinit
x = 1
mref id,2
return id
#global
#module B y
#modinit
newmod y, A : delmod y //殻だけ作る
mref id,2
return id
#modfunc local add
newmod y, A
return stat
#modfunc local dupvar var _y
dup _y, y
return
#global
newmod z, B
repeat 3
add@B z(0) : mes "y("+stat+") in z(0) is used."
loop
dupvar@B z(0), y
delmod y(1) : mes "y(1) in z(0) is deleted."
add@B z(0) : mes "y("+stat+") in z(0) is used."
if (varuse(y(1)) != 0) : mes "y(1) in z(0) is used."
原因が分かる方がいましたら、教えていただけると助かります。
|
|
2016/6/24(Fri) 16:14:01|NO.75967
(↑に続けて)
必要があって↑のような奇天烈な使い方をしています。
最終行の (varuse(y(1)) で「パラメーターの型が違います」というエラーが出ます。
その直上2行の動作を見る限り delmod y(1) は機能しているようです。
※「//殻だけ作る」なるコメント付きの行は関係ないので消しても問題ありません。
|
|
2016/6/24(Fri) 17:06:42|NO.75970
おそらく、dupされたモジュール変数に対してはvaruseが使えないから
ではないでしょうか。
dupされたモジュール変数はvaruse対応フラグを持っていないようです。
// test
#module Mod x
#defcfunc getpval var v, local pval
mref pval, 0
return pval
#define HSPVAR_SUPPORT_VARUSE 128
#defcfunc has_pval_hspvar_support_varuse var _v
dupptr pv, getpval(_v), 48
if (wpeek(pv, 36) & HSPVAR_SUPPORT_VARUSE) : return "true" : else : return "false"
#global
z = 0
mes has_pval_hspvar_support_varuse(z)
newmod a, Mod
mes has_pval_hspvar_support_varuse(a)
mes varuse(a)
dup b, a
mes has_pval_hspvar_support_varuse(b)
; mes varuse(b) ; error occurs
|
|
2016/6/24(Fri) 17:41:24|NO.75972
>(--) さん
ありがとうございます。dup すると varuse 非対応になるとは知りませんでした。
現状、foreachを回してヒットするかしないかで(使用済み/未使用)を判別する汚い方法でなんとか回している状態です。
varuse が使えれば1行で済むのですが...困った仕様ですね。
ひとまず原因がわかったので解決とします。
が、もし何らかの上手い回避策を思いついた方がいましたら、書き込んでいただけると助かります。
|
|
2016/6/25(Sat) 08:43:05|NO.75993
うーん、無理くりやるならこんな感じですかね…
// test
#module Mod x
#defcfunc varuse_for_dupped var dupped
mref pval, 0
mref aptr, 1
dupptr pv, pval, 48
dupptr fv, lpeek(pv, 28) + aptr, 16
return wpeek(fv, 0)
#global
newmod a, Mod
dup b, a
mes varuse_for_dupped(b) // => 1
delmod b
mes varuse_for_dupped(b) // => 0
ただ当方の環境では、newmodを繰り返し実行することによって配列にした
モジュール変数をdupした変数が、正しい長さを保持しない(length()が
間違っている)という不具合が起こりました。
スカラーなら問題ないと思いますが、配列では上手く行かないかも知れません。
|
|
2016/6/25(Sat) 12:08:19|NO.75995
>(--) さん
ありがとうございます。参考になりました。確かに、配列にすると駄目なようですね。
下のようにすると機能しなくなりました。
// test
#module Mod x
#defcfunc varuse_for_dupped var dupped
mref pval, 0
mref aptr, 1
dupptr pv, pval, 48
dupptr fv, lpeek(pv, 28) + aptr, 16
return wpeek(fv, 0)
#global
newmod a, Mod
newmod a, Mod
dup b, a
mes varuse_for_dupped(b(1))
delmod b(1)
mes varuse_for_dupped(b(1))
|
|
2016/6/25(Sat) 16:55:32|NO.75998
↑のスクリプトで機能しなくなったのは私のミスでした。
// test(修正版)
#module Mod x
#defcfunc varuse_for_dupped var dupped
mref pval, 0
mref aptr, 1
dupptr pv, pval, 48
dupptr fv, lpeek(pv, 28) + aptr * 16, 16
return wpeek(fv, 0)
#global
/* ついでに */
#module
#defcfunc getpval var _, local _pval
mref _pval, 0
return _pval
#deffunc adjust_length var dupped, var original
dupptr pv_dup, getpval(dupped), 48
dupptr pv_orig, getpval(original), 48
memcpy pv_dup, pv_orig, 20, 4, 4
return
#global
repeat 10
newmod a, Mod
loop
dup b, a
; ここでコケる
;foreach a
; mes varuse_for_dupped(b.cnt)
;loop
; なぜなら
mes length(a)
mes length(b)
adjust_length b, a
mes length(a)
mes length(b)
repeat length(b)
mes varuse_for_dupped(b.cnt)
loop
// 適当に消す
delmod b.0
delmod b.2
delmod b.3
delmod b.5
delmod b.7
mes
repeat length(b)
mes varuse_for_dupped(b.cnt)
loop
ご参考まで。
|
|
2016/6/25(Sat) 18:35:01|NO.76001
>(--) さん
度々ありがとうございます。上手く動くのを確認しました。
これで所望の動作が実現できそうです。
しかし、HSPもこの辺りまでくると結構脆い作りになっているんですね。驚きました。
|
|