2013年6月7日金曜日

実行時におかしい動作をする/コンパイルエラーが出る時に調べる点(随時追記)

実行時におかしい動作をした時に調べる点をあげておきます。

・表示がおかしい(1)
文字、文字列の表示そのものや、tatrb()/tcolor()で表示属性をつけた時に、おかしな表示になる時は、まずは文字コードを疑ってください。

X-BASIC for iOSの標準の文字コードはUTF-8です。
このコードはASCII範囲(&h20〜&h7e)こそ1バイトでSHIFT-JISと同じですが、半角カナや全角文字は全くコードが異なります。

このため、ASCIIにしか対応してない文字列関数やstr[i]による文字列内1バイト取り出しを使うと、予期しないコードを返すことがあり、またそれを表示しようとすると、表示そのものだけでなく属性も正常に処理されません。

どうしても内部処理を SHIFT−JISで行いたいときは、強制SHIFT-JISモードをオンにしてください。

なお、X-BASIC for iOSにはX68にあった、複数バイトコードは1バイトずつ出力しても正常表示される、という機能はありません。これは強制SHIFT-JISモードでも同じです。


・表示がおかしい(2)
タッチエリアを画面外にまたぐように設定すると、以後のテキスト表示がおかしくなることがあるようです。
タッチエリアは必ず画面内に収まるように設定してください。

・表示がおかしい(3)
画面がちらつくときは、vpriority()の引数も確認してみてください。
例えば、vpriority(TPAGE,B_SPAGE,GPAGE0,GPAGE1,GPAGE2,GPAGE3)とかすると画面がちらつく上テキスト画面が表示されなくなります。定数名が間違っている=引数の値が異常になっているのが原因です。
エラーが出ないのでわかりにくいですが、おかしい時は、まず引数を確認して下さい。

・画面が表示されない
グラフィックもしくはスプライト 画面を非透明の黒で描画していませんか?
X68では黒=透明でしたが、iOSでは黒と透明は厳密に異なります。
黒は透過しませんので、それでうめつくされた画面より優先順位が下になる画面は見えなくなります。特にBG画面は、設定によっては1スプライトの設定で全画面非透明になることがあるので要注意です。
vpriority()で優先順位を入れ替えて表示が見えるようになる場合は、100%これが原因です。

・TABをはじめコントロールコードが表示されてない
仕様書をよく読みましょう。
iOS版では高速化のため、コントロールコードはその1文字だけ表示する場合のみ処理されます。
従って、freads()などで読み込んだテキストファイル内文字列をそのままprintすると、結果が異なることになります。
内部的には、';'や','で区切った場合も別表示と見なしますので、うまく処理するとよいでしょう。

・ case 定数=値と書いていてもエラーにならない
これは、定数と値の比較式を評価した結果をcase値にしているからです。人間の理解上では間違っているように見えますが、BASICの式としては正しいのでエラーにはなりません。
すなわち、定数=値は比較式であり、このように実質上定数の比較式はコンパイル時に演算されてしまいます。
この場合、もし定数=値ならばcase -1相当で有り、定数<>値ならcase 0相当となります。
だから、エラーにならないのです。
もし、case -1またはcase 0相当式が同一swicth~endswitch内にあれば、エラーになります。

・bitmapでfdirect=YESなのに描画データが読めない
100%、apage()が描画対象のページ以外になっています。
確認してください。

・タッチキーでエリア外なのにキーコードが返ってくる
タッチエリアを、全く同じ座標域で重複設定している場合に発生します。
ループで処理を戻す場合などは、必ず、前回の設定をremoveTouchArea()で解除してから再設定してください。

・line()などでstyleを設定しても思った通りに描画されない。
styleの設定値にはiOSによる制約があります。そのためX-BASIC/68と同じ値を設定しても同じ描画になるとは限りません。
詳しくは取説をご覧ください。

・a=b=cの結果が違う
C言語ではこの式は
     b=c
     a=b
と等価で、a/b共にcの値が代入されますが、X-BASICでは
     a=(b=c)
と等価であり、(b=c)すなわち、bとcが等しいかどうかの評価結果がaに代入されます。
(その値はtrue=-1またはfalse=0です。)
Cから移植すると間違いやすいので注意してください。

・if 文でandを使う時の式評価順に注意
X-BASICのandは、C言語の&&とは意味が異なります。それは&に相当します。それぞれの意味は以下のようになります。
X-BASIC;if A and B
AとBを両方評価し、結果をandする。
だから、常にA式とB式両方が評価されます。

C ; if (A && B)
Aを評価し、成立したらBを評価する。
だから、Bは評価されないことがあります。

C ; if (A & B)
AとBを評価し、結果を&する。
だから、常にA式とB式両方が評価されます。
X-BASICのandはこちらに相当します。

ということなので、X-BASICでAが成立する時だけBが評価されることを想定するなら、
if A then {
    if B then ...
}
と記述する必要があります。

・func文の所で変数二重宣言エラーが発生する
関数の引数名が関数名と同じだったとき発生します。
関数の引数名は関数名と同じにしないでください。

なおこれはX-BASIC/68では発生しませんが、ぺけ-BASICで発生します。
両者の数少ない非互換部分です。


・落ちる/iOSに戻ってしまう
V2.4ではかなり安定しています。
この状態でも落ちるのは、再帰呼び出しが深すぎることがほとんどです。
例えば
func f()
  f()
endfunc
とすれば、確実に落ちます。再帰呼び出しでスタックを使い尽くすためです。残念ながら、iOSレベルでスタックの残り量を知るすべが無いため、安全性のチェックはなされていません。
V2.6では再帰呼び出し段数(正確には再起でなく異なる関数の呼び出し続けも同じ)に制約をつけましたので、関数内部でのローカル変数定義数にもよりますが、およそ落ちることはなくなるはずです。

あともう1つ、X-BASIC/68で書き込まれたfloatのデータを(ファイルを経由して)そのままiOS版で表示しようとすると落ちることがあります。浮動小数点数値フォーマットが異なるため、表示できずこうなります。
float6880()で変換して表示してください。


・関数呼び出しのある行で未宣言変数、関数、配列のエラーが出る
これはほぼ100%関数宣言側に問題があります。
funcがfuneになっているとか。


・X-BASIC/68作られたファイルを読むと値が異なる
この理由はメモリ上におけるデータのバイト並びの違いによります。68000はいわゆるビッグエンディアンでH→Lの順で格納されますが、iOS機器のARMはリトルエンディアンでL→H順です。
交互変換にはint6880()やfloat6880()関数を使います(V2.5以降で有効)。
なお、スプライトなどのパレットデータについては、さらに色コードの違いもあります。
x68Color2iOSColor()で変換します。

0 件のコメント:

コメントを投稿