HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2013
0619
y.tack{}無しifが変な動作をする気がする書き方4解決


y.tack

リンク

2013/6/19(Wed) 00:21:09|NO.55067

バグか仕様かわからないけど 一応報告です
元は公式BBSに書いたモジュールのリファクタで
指定のbitが1か0か調べるものです

変なerrorになる

#module #deffunc bit_ls_init ldim Bs,9 Bs(1)=*bit_1 Bs(2)=*bit_2 Bs(3)=*bit_3 Bs(4)=*bit_4 Bs(5)=*bit_5 Bs(6)=*bit_6 Bs(7)=*bit_7 Bs(8)=*bit_8 return #defcfunc is_bit int n,int m ;if (n < 1)or(n >8){ ;dialog "error",1 ;return-1 ;} goto Bs(n) dialog "error",1 return-1 *bit_1:if m&1:return 1:return 0 *bit_2:if m&2:return 1:return 0 *bit_3:if m&4:return 1:return 0 *bit_4:if m&8:return 1:return 0 *bit_5:if m&$10:return 1:return 0 *bit_6:if m&$20:return 1:return 0 *bit_7:if m&$40:return 1:return 0 *bit_8:if m&$80:return 1:return 0 #global bit_ls_init mes is_bit(2,3) mes is_bit(3,3) mes ; mes is_bit(0,3) mes is_bit(1,3) mes is_bit(8,3) ; mes is_bit(9,3)

こう書けば回避できる

#module #deffunc bit_ls_init ldim Bs,9 Bs(1)=*bit_1 Bs(2)=*bit_2 Bs(3)=*bit_3 Bs(4)=*bit_4 Bs(5)=*bit_5 Bs(6)=*bit_6 Bs(7)=*bit_7 Bs(8)=*bit_8 return #defcfunc is_bit int n,int m ;if (n < 1)or(n >8){ ;dialog "error",1 ;return-1 ;} goto Bs(n) dialog "error",1 return-1 *bit_1:if m&1{return 1}return 0 *bit_2:if m&2{return 1}return 0 *bit_3:if m&4{return 1}return 0 *bit_4:if m&8{return 1}return 0 *bit_5:if m&$10{return 1}return 0 *bit_6:if m&$20{return 1}return 0 *bit_7:if m&$40{return 1}return 0 *bit_8:if m&$80{return 1}return 0 #global bit_ls_init mes is_bit(2,3) mes is_bit(3,3) mes ; mes is_bit(0,3) mes is_bit(1,3) mes is_bit(8,3) ; mes is_bit(9,3)

else:if
がたぶん上手く動くってことなんですけど
どうだと上手く動いて
どうだと上手く動かないかの
調査も誰かしないかなー
そういうのがないと安心して使えないです



この記事に返信する


ツノン

リンク

2013/6/19(Wed) 06:59:39|NO.55071


*bit_1:if m&1:return 1:return 0 *bit_2:if m&2:return 1:return 0 *bit_3:if m&4:return 1:return 0 *bit_4:if m&8:return 1:return 0 *bit_5:if m&$10:return 1:return 0 *bit_6:if m&$20:return 1:return 0 *bit_7:if m&$40:return 1:return 0 *bit_8:if m&$80:return 1:return 0
の部分の処理分岐が上手く出来ていないせいか スクリプトに記述されている return 0 が全て無意味な状態です。
if は 最初の改行まで、または { で始まって } で終わる 領域 の内部を、条件に合致した場合の処理に充てる命令なので
このスクリプトでは、条件に合致した場合は return 1 合致しない場合は return 0 を無視して、再び次のラベルへ移動してしまっているようです。
#global プリプロセッサ命令は 実は ただのラベル名で有るので。制御がそこで止まる事は有りません。
おかげで wait を 挟まない無限ループの様な状況が生まれており、こうなると、アプリケーションは応答なしの状態になり止まってしまいます。

起こっている現象の簡単な再現
y.tack さんスクリプトは いうなればこのような状況に有ります。

#module mod #deffunc test #global test
よってプリプロセッサによるスクリプト展開時にこのような形に変換され

goto*mod_eof #deffunc test *mod_eof test
test と #deffunc test の間で無限ループが発生します。

もし 55067 のスクリプトを使用するのであれば、必ず モジュールの最後に wait または await を挟んでください。



ツノン

リンク

2013/6/19(Wed) 07:09:59|NO.55073

追記
指定の位置のビットの状態を調べるのでしたら。以下のようなスクリプトで可能です。

// %1 調べる数値 // %2 0 から始まる ビットの位置を示す値。 #define ctype is_bit(%1,%2) %1&(1<<%2) val = 0b0010 // あえて一番目を立てる。 mes is_bit(val,1) // 戻り値が 0 以外であるなら そのビットは立っている。
ちなみに<< >> はビットシフト演算子と言って、右辺の数値だけ、左辺のビットをずらす作用が有ります。
よって
1<<0 は 1
1<<1 は 2
1<<2 は 4
となります



ツノン

リンク

2013/6/19(Wed) 07:16:07|NO.55074

更に追記
 一度 マニュアルを読んでみた方が良いかも。
 マニュアルには、hspプログラミングをするうえでで知っていた方がよい情報が多く載っています。

 



y.tack

リンク

2013/6/19(Wed) 08:19:52|NO.55078

>if は 最初の改行まで、または { で始まって } で終わる 領域 の内部を、条件に合致した場合の処理に充てる命令なので
なるほど{}なしのifって改行までのブロックだったんですか
一つの式だけが対象だと思ってました
訳のわからないことを書いてしまって悔しいですが
丁寧に説明していただけたので削除しない方が良さそうですね


#module #deffunc bit_ls_init ldim Bs,9 Bs(1)=*bit_1 Bs(2)=*bit_2 Bs(3)=*bit_3 Bs(4)=*bit_4 Bs(5)=*bit_5 Bs(6)=*bit_6 Bs(7)=*bit_7 Bs(8)=*bit_8 return #defcfunc is_bit int n,int m ;if (n < 1)or(n >8){ ;dialog "error",1 ;return-1 ;} goto Bs(n) dialog "error",1 return-1 *bit_1:if m&1:return 1 return 0 *bit_2:if m&2:return 1 return 0 *bit_3:if m&4:return 1 return 0 *bit_4:if m&8:return 1 return 0 *bit_5:if m&$10:return 1 return 0 *bit_6:if m&$20:return 1 return 0 *bit_7:if m&$40:return 1 return 0 *bit_8:if m&$80:return 1 return 0 #global bit_ls_init mes is_bit(2,3) mes is_bit(3,3) mes ; mes is_bit(0,3) mes is_bit(1,3) mes is_bit(8,3) ; mes is_bit(9,3)
あえてそうしたいならこうすれ。と



ONION software Copyright 1997-2023(c) All rights reserved.