Why Pascal const arrays aren't actually constants?
Program ConstTest;
Const constVar = 1;
Begin
constVar := 3;
WriteLn(constVar);
End.
It's pretty obvious that the above code will not compile, because it's not right to change the value of a constant. However, following code will comp开发者_StackOverflow中文版ile, and will return "1; 5; 3;", even though the array is a const:
Program ConstTest;
Const constArr:Array [1..3] Of ShortInt = (1,2,3);
Var i:ShortInt;
Begin
constArr[2] := 5;
For i:=1 To 3 Do WriteLn(constArr[i],'; ');
End.
So, what causes this behavior? Why a constant isn't actually a constant?
I'm using FreePascal Compiler 2.2.0 for Win32.
What you have there is a typed constant. Typed constants are distinct from ordinary constants (a.k.a. true constants), which is what your constVar
is. Notice how you didn't need to specify a type on constVar
; if you had, you may see that the compiler allows you to assigned new values to it, too:
const
constVar: Integer = 1;
The Free Pascal manual describes typed constants:
Contrary to ordinary constants, a value can be assigned to them at run-time. This is an old concept from Turbo Pascal, which has been replaced with support for initialized variables: For a detailed description, see section 4.4, page 183.
Support for assigning values to typed constants is controlled by the
{$J}
directive: it can be switched off, but is on by default (for Turbo Pascal compatibility). Initialized variables are always allowed.
For an initialized variable, replace const
with var
in your declaration. It will get its value upon entering scope. Or, turn off the $J
directive prior to the typed-constant declaration:
{$J-}
const
constArr: array [1..3] of ShortInt = (1, 2, 3);
{$J+}
Whether you turn it back on afterward is up to you.
Typed constants are modifiable because of the way they're stored in memory. In fact, it's because they're stored in memory that they were originally modifiable. Ordinary constants aren't stored in memory as distinct objects. When the compiler encounters an ordinary constant used in your program, it replaces it in-line with the constant's value, just as though you'd used a literal in its place. A typed constant, on the other hand, resides in its own location in memory, and when you refer to one in code, its value is read from memory, just like using any other variable. You use typed constants when there is no syntax available for a literal — you can't have array or record literals, for instance.
Well, if you also know C, here's a few analogies:
In [Turbo/Free] Pascal, writing something like this:
const
MIN = 5;
MAX = 10;
Is equivalent to doing this in C:
#define MIN 5
#define MAX 10
That is, it's a compile time symbol replace like the other poster says.
With records and arrays, (typed constants), the "const" expression is just a way of initializing a block of memory associated with a linker symbol.
TODO: counter example.
精彩评论