constant
を使用すると、 固定値を宣言し、 名前でそれを参照できます。 例:
12 Constant INCHES-PER-FOOT 3E+08 fconstant SPEED-O-LIGHT
Variable
は読み取りと書き込みの両方ができるため、 その実行時の振る舞いは、 現在の値を操作できるアドレスを提供することです。
それとは対照的に、 Constant
の値は一度宣言すると変更できないため、 アドレスを指定する必要はありません14
– 定数の値を直接返す方が効率的です。 そして正にそのとおりになります。 つまり、
定数の実行時の効果は、その値をスタックの頂上に置くことです((Constant
を実装する方法の1つは User-defined Defining Words で見つけることができます)。
Forth は、それぞれ2倍長定数と浮動小数点定数を定義するための 2Constant
と fconstant
も提供します。
Constant
( w "name" – ) core “Constant”
定数 name を値 w で定義します。
name 実行時: – w
AConstant
( addr "name" – ) gforth-0.2 “AConstant”
constant
と似ていますが、 アドレスのための定数を定義します(これはクロス・コンパイラーでのみ違いが生じます)。
2Constant
( w1 w2 "name" – ) double “two-constant”
fconstant
( r "name" – ) floating “f-constant”
Forth の定数は、他のプログラミング言語の定数とは異なる振る舞いをします。 他の言語では、 定数(アセンブラーの EQU や C の #define など)はコンパイル時にのみ存在します。 実行プログラム(executable program)では、 定数は即値(absolute number)に変換されているため、 シンボリック・デバッガを使用しない限り、 その数値がどのような抽象的なものを表しているかを知ることは不可能です。 Forth では、 定数はヘッダー空間にエントリを持ち、 それを使用するコードが定義された後もそこに残ります。 実際、 実行時に機能する義務があるため、 それをディクショナリに残しておく必要があります。 例:
12 Constant INCHES-PER-FOOT : FEET-TO-INCHES ( n1 -- n2 ) INCHES-PER-FOOT * ;
ここで、 FEET-TO-INCHES
が実行されると、 定数 INCHES-PER-FOOT
に関連付けられた xt
が実行されます。 see
を使用して FEET-TO-INCHES
の定義を逆コンパイルすると、
INCHES-PER-FOOT
を呼び出していることがわかります。 一部の Forth
コンパイラーは、定数を使用する場所にインライン展開(in-lining)することによって定数を最適化しようとします。 以下のようにして Gforth
に定数をインライン化するように強制できます:
: FEET-TO-INCHES ( n1 -- n2 ) [ INCHES-PER-FOOT ] LITERAL * ;
ここで、 see
を使用して FEET-TO-INCHES
の このバージョンを逆コンパイルすると、
INCHES-PER-FOOT
が存在しないことがわかります。 これがどのように機能するかを理解するには、
Interpret/Compile states と Literals を読んでください。
この方法で定数をインライン化すると、 実行時間がわずかに改善される可能性があり、 定数がコンパイル時にのみ参照されるようにすることができます。 ただし、 定数の定義はまだディクショナリーに残っています。 一部の Forth コンパイラーは、 一時的なワード(transient words)を保持する 2 番目のディクショナリーを制御するメカニズムを提供し、 メモリー領域を回復するために後でこの 2 番目のディクショナリーを削除できるようしています。 ただし、 これを行う標準の方法はありません。
まあ、
多くの場合、 それは可能ではありますが、 標準的な移植可能な方法では変更できません。 Value
を使用する方が安全です
(続きを読んでください)まあ、多くの場合変更できますが、標準的な移植可能な方法では変更できません。 Value
(続きを読んでください)