Почему константные массивы Паскаля на самом деле не являются константами? - PullRequest
11 голосов
/ 13 июля 2010
  Program ConstTest;
  Const constVar = 1;
  Begin
    constVar := 3;
    WriteLn(constVar);
  End.

Совершенно очевидно, что приведенный выше код не будет компилироваться, потому что неправильно менять значение константы. Однако следующий код скомпилируется и вернет «1; 5; 3;», даже если массив является константой:

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.

Итак, что вызывает это поведение? Почему константа на самом деле не является константой?

Я использую FreePascal Compiler 2.2.0 для Win32.

Ответы [ 2 ]

11 голосов
/ 14 июля 2010

То, что у вас есть, это напечатанная константа . Типизированные константы отличаются от обычных констант (a.k.a. истинных констант ), которыми являются ваши constVar. Обратите внимание, что вам не нужно указывать тип для constVar; если вы это сделали, вы можете увидеть, что компилятор также позволяет вам присваивать ему новые значения:

const
  constVar: Integer = 1;

Руководство Free Pascal описывает типизированные константы:

В отличие от обычных констант, им может быть присвоено значение во время выполнения. Это старая концепция Turbo Pascal, которая была заменена поддержкой инициализированных переменных: подробное описание см. В разделе 4.4 , стр. 183 .

.

Поддержка присвоения значений типизированным константам контролируется директивой {$J}: ее можно отключить, но она включена по умолчанию (для совместимости с Turbo Pascal). Инициализированные переменные всегда разрешены.

Для инициализированной переменной замените const на var в вашем объявлении. Он получит свое значение при входе в область видимости. Или отключите директиву $J перед объявлением типизированной константы:

{$J-}
const
  constArr: array [1..3] of ShortInt = (1, 2, 3);
{$J+}

Независимо от того, включите ли вы его позже, вам решать.


Типизированные константы можно изменять из-за способа хранения в памяти. На самом деле, это , потому что они хранятся в памяти, которую они изначально можно было изменить. Обычные константы не хранятся в памяти как отдельные объекты. Когда компилятор встречает обычную константу, используемую в вашей программе, он заменяет ее in-line значением константы, как если бы вы использовали вместо него литерал. Напечатанная константа, с другой стороны, находится в своем собственном месте в памяти, и когда вы ссылаетесь на нее в коде, ее значение читается из памяти, как и любая другая переменная. Вы используете типизированные константы, когда для литерала нет синтаксиса - например, у вас не может быть литералов массива или записи.

0 голосов
/ 21 апреля 2012

Ну, если вы также знаете C, вот несколько аналогий:

В [Turbo / Free] Pascal, напишите что-то вроде этого:

const
     MIN = 5;
     MAX = 10;

Это эквивалентно выполнению этого в C:

#define MIN 5
#define MAX 10

То есть это символ времени компиляции, как говорит другой постер.

Для записей и массивов (типизированных констант) выражение "const" - это просто способ инициализации блока памяти, связанного с символом компоновщика.

TODO: контрпример.

...