Node:Constants, Next:Values, Previous:Variables, Up:Defining Words
Constant allows you to declare a fixed value and refer to it by
name. For example:
12 Constant INCHES-PER-FOOT 3E+08 fconstant SPEED-O-LIGHT
Variable can be both read and written, so its run-time
behaviour is to supply an address through which its current value can be
manipulated. In contrast, the value of a
Constant cannot be
changed once it has been declared1 so it's not necessary to supply the address - it is more
efficient to return the value of the constant directly. That's exactly
what happens; the run-time effect of a constant is to put its value on
the top of the stack (You can find one
way of implementing
Constant in User-defined Defining Words).
Forth also provides
fconstant for defining
double and floating-point constants, respectively.
Define a constant name with value w.
Constantw "name" -- core ``Constant''
name execution: - w
2Constantw1 w2 "name" -- double ``two-constant''
fconstantr "name" -- float ``f-constant''
Constants in Forth behave differently from their equivalents in other
programming languages. In other languages, a constant (such as an EQU in
assembler or a #define in C) only exists at compile-time; in the
executable program the constant has been translated into an absolute
number and, unless you are using a symbolic debugger, it's impossible to
know what abstract thing that number represents. In Forth a constant has
an entry in the header space and remains there after the code that uses
it has been defined. In fact, it must remain in the dictionary since it
has run-time duties to perform. For example:
12 Constant INCHES-PER-FOOT : FEET-TO-INCHES ( n1 -- n2 ) INCHES-PER-FOOT * ;
FEET-TO-INCHES is executed, it will in turn execute the xt
associated with the constant
INCHES-PER-FOOT. If you use
see to decompile the definition of
FEET-TO-INCHES, you can
see that it makes a call to
INCHES-PER-FOOT. Some Forth compilers
attempt to optimise constants by in-lining them where they are used. You
can force Gforth to in-line a constant like this:
: FEET-TO-INCHES ( n1 -- n2 ) [ INCHES-PER-FOOT ] LITERAL * ;
If you use
see to decompile this version of
FEET-TO-INCHES, you can see that
INCHES-PER-FOOT is no
longer present. To understand how this works, read
Interpret/Compile states, and Literals.
In-lining constants in this way might improve execution time fractionally, and can ensure that a constant is now only referenced at compile-time. However, the definition of the constant still remains in the dictionary. Some Forth compilers provide a mechanism for controlling a second dictionary for holding transient words such that this second dictionary can be deleted later in order to recover memory space. However, there is no standard way of doing this.
Well, often it can be -- but
not in a Standard, portable way. It's safer to use a