ABのタイプキャスト問題

型チェックの甘さが問題になっていることについて、考えをまとめてみます。


元々、Basic言語というヤツはタイプチェックしてないっぽいですよね(--;;;。あったとしても、数値型と文字列型の判別くらいでしょうか…。


10 a="1"
20 b=2
30 c=a+b
40 Print c '3と表示される


元祖Basicでは、上記のようなプログラムが平気で実行できてしまいます。インタプリタBasicでは変数管理がどのようになされていたのか、わからない部分ではありますが、ネイティブコンパイラのそれと比べて柔軟な自動タイプキャストがなされていたことは事実なようです。


で、そういう風潮を受けつつ開発を進めたABなんで、型チェックの甘さがあって当然なんですね〜。元々の言語仕様に「タイプキャスト」という概念が無いんですから。


さてさて、コミュニティフォーラムのほうで話題になったのは、「Long型変数へBytePtr型データを代入するとエラーになるが、パラメータ引き渡し時にはエラーにならない」という問題です。


実はこいつ、結構厄介な問題なんです。一見すると、Long型にポインタ型を強制的に代入しようとしているんだから、ネイティブコンパイラとしてのABではエラーになって当然なのですが、Win32APIとの連携・柔軟性を考えると100%そうともいえないのです。SetWindowLong関数を例にあげて説明してみましょうか…


Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(hWnd As HWND, _
nIndex As Long, _
NewLong As Long) As Long


Win32APIの一つであるSetWindowLong関数、第3パラメータ、NewLongというパラメータに注目してみてください。こいつはLong型であることがわかるのですが、ヘルプでは「32 ビット整数値」と記されているんです。32ビット整数値…Win32上で作動するWindows環境では、これに当てはまる値は沢山あるはずです。Long型、DWord型はもちろんのこと、ハンドル、ポインタ、RGB値と、色々挙げることができます。

  • GWL_EXSTYLE 拡張ウィンドウスタイルを変更します。
  • GWL_STYLE ウィンドウスタイルを変更します。
  • GWL_WNDPROC ウィンドウプロシージャのアドレス、またはウィンドウプロシージャのアドレスを示すハンドルを変更します。
  • GWL_HINSTANCE アプリケーションのインスタンスハンドルを変更します。
  • GWL_ID ウィンドウの ID を変更します。
  • GWL_USERDATA ウィンドウに関連付けられたアプリケーション定義の 32 ビット値を変更します。

こういう具合にNewLongには、ウィンドウスタイル(Long型)、ハンドル(DWord型)、プロシージャアドレス(ポインタ型)を指定することになるのですが、肝心のAB Ver4.0にはタイプキャストをユーザーが任意で行える環境が備わっていないんです。となると、ある程度のタイプキャストは自動的に行ってユーザーの負担を減らすというのが自然な流れになり、Win32API呼び出し(関数呼び出し)に限り、タイプキャスト(特にLong型へポインタを…)が甘くなってくるんです。


しかしABには、C/C++Delphiなどの高級コンパイラ言語に対抗するだけの仕様を持たせたいって願いもあるんですよね。長いことABユーザーをやられている方、またはABウォッチャーの方は私がそういう姿勢でコンパイラ製作に取り組んでいることは薄々感ずいていることと思います。


仕様がなければ、追加すればいい。これにつきます。


しかし、過去のプログラム資産(Ver3.x、Ver4.04.00までに製作されたソースコード)を無効にしてしまうような仕様変更はできないので、注意して取り組まなければなりません。


原案として、#strictディレクティブを再出現させようか検討中です。これを導入したら、CDbl、CSng、CIntなどのタイプキャスト関数をコンパイラに組み込んで演算過程で評価していかなくちゃなりません。


実は、#strictってVer2.xのときにあったんです。覚えてる方、いますでしょうか??当時は暗黙の宣言を禁止する目的で指定するディレクティブだったのですが、Ver3.0から消え去ったので、型チェックを厳密に行うための識別子として利用しようってことです。←またまたC/C++みたいって言われちゃいそうですけど(^^;;;