処理前分岐
今回は、処理の前に分岐するディレクティブを紹介します。
処理中での分岐ではなく、処理の前に分岐…?
分岐も処理なのでは?という問いが聞こえてきそうですが、
前章と同じく、ココでの前処理というのはプリプロセス、コンパイル前に行う処理。
コンパイル実行前に分岐するということは即ち、コンパイル自体を制御するということです。

初めに、分岐を行うif命令にプリプロセス接頭辞#を付けた命令と、
switch命令に対するswend命令のように、始端と終端を対にして使う必要があるので併せて紹介します。
#if 定数
定数分岐対象とする定数値、または定数式を指定する。
#endif
[パラメータなし]終端を示すだけのため、パラメータは必要ない。
パラメータは定数とありますが、つまりは変数を指定できないということです。 この命令は、あくまでコンパイル前に行う処理であり、 コンパイル後に変動させられる変数値を指定しても理解できずにシンタクスエラーとなってしまいます。 定数値…つまり、プログラマ自身がスクリプト上に直接埋め込むんだから、 分岐させなくても結果はプログラマ自身がわかっていること。なんでこんな命令が存在するのか? そう思う人も少なくないことでしょう。 ヘルプに記述されていますが、拡張マクロを使用する場合に自動的に追加されるマクロが幾つか存在します。

マクロ名マクロ内容
_debugデバッグモード時
__hsp30__HSP3.0以降使用時
__file__使用時点で解析されているファイル名 
__line__使用時点で解析されている行番号
__date__使用時点の日付
__time__使用時点の時刻
__hspver__HSPバージョン番号

#if命令は定数値が真(0以外)なのか、偽(0)かで分岐を行うものなので用途がかなり限定されます。 使い道として一番多いのは、ユーザー定義命令を作成した時のサンプル部分に使用するというものですが、 現段階ではユーザー定義命令を説明していないのでココでは紹介しません。 代わりに「スクリプトからの実行をHSP3.0以降で行っているか」を例に書いてみましょう。 尚、「偽」の場合にも処理を行わせたい場合(ココではHSP2.X以前)、 if命令のelseと同じ効果である次の命令を使います。
#else
[パラメータなし]「真」以外を示すだけのため、パラメータは必要ない。
使い方もelse同様に、始端から終端までの間に置きます。
 1
 2
 3
 4
 5
 6
 7
 8
 9
	ver = __hspver__ 			// 上位8ビット:メジャー 下位8ビット:マイナー

#if __hspver__ >= 0x3000			// 上記のverは変数なので指定できない
	mes "バージョン=" + strf("%x", ver)	// HSP2.Xには存在しないがエラーにはならない
#else
	str ver, 16				// HSP3.0から関数だが、エラーにはならない
	mes "バージョン=" + ver
	stop
#endif
次に、#if命令に比べると、まだ利用頻度は高いであろうプリプロセス命令を紹介します。
#ifdef マクロ定数
マクロ定数対象とするマクロ定数名を指定する。
この命令はスクリプト上で#ifdef命令以前に、 パラメータで指定したマクロ定数が定義されているなら処理(=コンパイル)するというものです。 逆を言えば、定数が定義されてないならコンパイルしないということですね、当たり前ですが。 スクリプトは複数ファイルに分割することができますが、 一度でも連結しているならば、二重で連結しないようにトラップを設けるという方法でよく利用されています。 また、自動的に追加される_debugマクロはデバッグ時のみ定義されるようで、 コレを利用し、デバッグ時にだけ表示される、ある処理にジャンプする…と言ったことが可能です。 尚、ブロック終端には、#if命令と同じく、#endif命令を置く必要があり、 「偽」の場合も、#if命令と同じく、#elseを使います。
 1
 2
 3
 4
 5
#ifdef _debug
	mes "現在デバッグで実行しています。"
#else
	mes "実行ファイルにして実行しています。"
#endif
この章の最後に紹介するのは、#ifdef命令の逆の処理を行う命令です。
#ifndef マクロ定数
マクロ定数対象とするマクロ定数名を指定する。
#ifdef命令の逆というのは、いわゆる「#ifdefブロックの#else部」を「真」として処理し、 #ifndefブロックの「偽」は「#ifdefブロックの真」の部分を処理するというものです。 要するに#ifndef命令以前に定数が定義されていないなら処理して、 定義されているならコンパイルしないというものです。 下記サンプルは、#ifdef命令の逆ということがわかりやすいように、逆処理を#ifndef命令で処理しています。
 1
 2
 3
 4
 5
#ifndef _debug
	mes "実行ファイルにして実行しています。"
#else
	mes "現在デバッグで実行しています。"
#endif
#ifdef命令と#else命令を使えば、#ifndef命令と同じことができるのになぜ用意されてるのか? 定数が定義されてない場合にだけ何らかの処理をしたいとき、 #ifndef命令を使うと、わざわざ定義済み時の空処理を書く手間がなくなり、見栄えもマシになるから。 多分ソレだけでしょう…。 さて、それではどういう場合に「定義されてない時だけ実行したい処理」があるでしょうか? 「処理しているプログラムファイルとは別のファイルを結合したい時」に利用できます。 現段階ではまだ紹介してないので、コレについてはその時に改めて紹介しようと思います。 現段階では「定義されてない時だけ実行したい処理もあるのだ」ということだけでも覚えておけば十分です。